8.5 KiB
safetwitch-backend
The backend for SafeTwitch
Documentation
API Endpoints
Disclaimer
Every endpoint can return a 500 status code, and it follows this schema:
{
status: "error",
message: "Error message..."
}
/api/users/:username
GET - :username is any streamer Gets a specific twitch streamer
Responses
200
The request was successful, returns data of type StreamerData Example:
{
"status": "ok",
"data": {
"username": "filian",
"about": "Welcome to my Vtuber alpha! 3D streaming and variety games! Join the discord! n_n",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy9mNzVkNDEwMy1hMjY1LTRlMjEtODhiNS00NDc0NWZjMWJmNDQtcHJvZmlsZV9pbWFnZS0zMDB4MzAwLnBuZw",
"followers": 579463,
"socials": [
{
"type": "discord",
"name": "discord.gg/filian",
"link": "https://discord.gg/filian"
},
{
"type": "twitter",
"name": "twitter.com/filianIsLost",
"link": "https://twitter.com/filianIsLost"
}
],
"isLive": false,
"isPartner": true,
"colorHex": "#8040E0",
"id": 198633200,
"stream": null
}
}
404
The streamer was not found
/api/discover
GET Gets the discover page of twitch, a list of categories
Responses
200
The request was successful, returns a Category[] Example:
{
"status": "ok",
"data": [
{
"name": "Just Chatting",
"displayName": "Just Chatting",
"viewers": 510365,
"tags": [
"IRL"
],
"createdAt": null,
"cursor": "eyJzIjoxLCJkIjpmYWxzZSwidCI6dHJ1ZX0=",
"image": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC90dHYtYm94YXJ0LzUwOTY1OC0yODV4MzgwLmpwZw"
},
...
}
/api/discover/:game
GET - :game is a name of a twitch category Gets a specific twitch category
Responses
200
The server found the category, returns data of type CategoryData[] Example:
{
"status": "ok",
"data": {
"name": "Just Chatting",
"cover": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC90dHYtYm94YXJ0LzUwOTY1OC0xNDR4MTkyLmpwZw",
"description": null,
"viewers": 533593,
"followers": 23147702,
"tags": [
"IRL"
],
"streams": [
{
"title": "CIERRE DEL MERCATO DE LA KINGS LEAGUE | ÚLTIMO DÍA DE MERCATO | ÚLTIMOS CLAUSULAZOS | SE VIENEN LLOROS",
"viewers": 60897,
"preview": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9wcmV2aWV3cy10dHYvbGl2ZV91c2VyX2liYWktNDQweDI0OC5qcGc",
"tags": [
"Español",
"KOI",
"KingsLeague"
],
"cursor": "eyJzIjo2MDg5Ny40NDU3NDY0NjY4NSwiZCI6ZmFsc2UsInQiOnRydWV9",
"streamer": {
"name": "ibai",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy81NzQyMjhiZS0wMWVmLTRlYWItYmMwZS1hNGY2YjY4YmVkYmEtcHJvZmlsZV9pbWFnZS01MHg1MC5wbmc",
"colorHex": "2A2B62"
}
},
...
]
}
}
404
The category was not found
/api/badges?streamerName=NAME
GET Gets global twitch chat badges
streamerName query is optional, if given it will only provide the badges for that streamer.
Responses
200
Server retrieved the badges, returns type Badge[] Example:
{
"status": "ok",
"data": [
{
"id": "getting-over-it_2;1;",
"setId": "getting-over-it_2",
"title": "Getting Over It",
"version": "1",
"images": {
"image1x": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9iYWRnZXMvdjEvYmI2MjBiNDItZTBlMS00MzczLTkyOGUtZDRhNzMyZjk5Y2NiLzE",
"image2x": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9iYWRnZXMvdjEvYmI2MjBiNDItZTBlMS00MzczLTkyOGUtZDRhNzMyZjk5Y2NiLzI",
"image4x": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9iYWRnZXMvdjEvYmI2MjBiNDItZTBlMS00MzczLTkyOGUtZDRhNzMyZjk5Y2NiLzM"
}
},
...
]
}
/api/search?query=SEARCHQUERY
GET - SEARCHQUERY is any string Searches for categories, streamers, tags, and live streamers. Returns data of type SearchResult
Responses
200
The server found the search data, returns: Example:
{
"status": "ok",
"data": {
"channels": [
{
"username": "filian",
"followers": 580066,
"isLive": false,
"about": "Welcome to my Vtuber alpha! 3D streaming and variety games! Join the discord! n_n",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy9mNzVkNDEwMy1hMjY1LTRlMjEtODhiNS00NDc0NWZjMWJmNDQtcHJvZmlsZV9pbWFnZS0xNTB4MTUwLnBuZw",
"isPartner": null,
"colorHex": "#fff",
"id": 198633200
},
...
],
"categories": [
{
"name": "Lilian: The beginning of the end",
"displayName": "Lilian: The beginning of the end",
"viewers": null,
"tags": [
""
],
"image": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9wcmV2aWV3cy10dHYvbGl2ZV91c2VyX2VsbHllbi0xMjgweDcyMC5qcGc"
}
],
"relatedChannels": [
{
"username": "EllyEN",
"about": "HI I'M ELLY❗❗ I'm a cwiminal Vtuber who loves cars, boba, games, & getting into trouble~❗❗",
"pfp": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9qdHZfdXNlcl9waWN0dXJlcy8xZjJjNmQ2Yi1hZmZmLTQ4NGYtYTdjMy1iNGRhZTU2MzllOGMtcHJvZmlsZV9pbWFnZS0zMDB4MzAwLmpwZWc",
"followers": 100538,
"socials": [
{
"type": "twitter",
"name": "Twitter",
"link": "https://www.twitter.com/EllyVtuber"
},
{
"type": "tiktok",
"name": "Tiktok",
"link": "https://www.tiktok.com/@ellyvtuber"
},
{
"type": "youtube",
"name": "YouTube",
"link": "https://www.youtube.com/EllyEN"
}
],
"isLive": true,
"isPartner": true,
"colorHex": "#FA2929",
"id": 141045387,
"stream": {
"title": "little bit of valheim THEN FFXIV! 🌱 I'M OBSESSED LOL | SUBATHON PART 2 DAY 16 | #AlienwareHive !GamerSupps",
"topic": "I'm Only Sleeping",
"startedAt": 1682363001000,
"tags": [
"LGBTQIA",
"NoBackseating",
"Vtuber",
"ENVtuber",
"English"
],
"viewers": 654,
"preview": "https://safetwitch.dragongoose.us/proxy/img/aHR0cHM6Ly9zdGF0aWMtY2RuLmp0dm53Lm5ldC9wcmV2aWV3cy10dHYvbGl2ZV91c2VyX2VsbHllbi0xMjgweDcyMC5qcGc"
}
},
...
],
"channelsWithTag": []
}
}
/api/emotes/:streamerName
GET Gets all of the emotes for a streamer
Resposnes
200
Returns the found Emotes Example:
{
"name": "fillyTailChase",
"urls": {
"1": "..."
}
},
...
Proxying Endpoints
/proxy/img/:base64Url
GET Proxies an image through the server :base64Url can be any base64 encoded Url
Responses
200
Server returns the requested image
404
The requested image was invalid
/proxy/stream/:username/hls.m3u8
GET Gets the m3u8 manifest for a streamer. This manifest will contain all stream qualities if they are live
Responses
200
Returns the manifest
400
The streamer is not live Example:
{
"status": "error",
"message": "Streamer is not live"
}
/proxy/stream/sub/:encodedUrl
GET Returns the m3u8 manifest for a specific quality under the master manifest
200
Returns the manifest file
/proxy/stream/segment/:encodedUrl
GET Gets a segment from one of the quality's manifest file. This is the actual video thats displayed on your screen
200
Returns the stream segment, HLS streaming.