REST endpoints
A handful of plain HTTP endpoints complement GraphQL where caching, streaming or file uploads make REST the better fit. Base URL: https://api.jiltv.app. Public GET endpoints can be tried right here.
Chat clients
/v1/channels/{platform}/{channelId}/bootstrapThe active emote set of a channel in a compact format. Load it once when joining a chat.
Auth: None · Cached: Edge cache with ETag; answers 304 when unchanged
Parameters
platform pathtwitch, kick or youtube
channelId pathThe channel ID on the platform, e.g. the numeric Twitch user ID.
GET https://api.jiltv.app/v1/channels/twitch/123456/bootstrap/v1/sets/globalGlobal emote sets, available in every channel.
Auth: None · Cached: Edge cache with ETag
GET https://api.jiltv.app/v1/sets/global/v1/resolve/twitch/{login}Turns a Twitch login into the channel ID, if the channel uses JilTV. 404 otherwise.
Auth: None · Cached: 5 minutes, 1 hour at the edge
Parameters
login pathTwitch login name, lowercase.
GET https://api.jiltv.app/v1/resolve/twitch/jilence/v1/personal-emotes/twitchPersonal emotes of chatters, by Twitch login: emotes a user may use in every channel. Batch the visible chatters; channel emotes take precedence over personal ones, personal over global.
Auth: None · Cached: 1 minute
Parameters
logins queryComma-separated Twitch logins, at most 100.
GET https://api.jiltv.app/v1/personal-emotes/twitch?logins=jilence/v1/events/channels/{platform}/{channelId}Server-Sent Events with live changes to the channel’s emote set. Browsers reconnect on their own. Details in Chat clients & realtime.
Auth: None
const events = new EventSource('https://api.jiltv.app/v1/events/channels/twitch/123456');
events.addEventListener('set.batch', (e) => {
const { set_id, added, removed, renamed } = JSON.parse(e.data);
});
events.addEventListener('channel.set_switched', () => reloadBootstrap());Cosmetics
/v1/cosmetics/catalogEvery published paint and badge with its design. Cache it; users only reference cosmetics by ID.
Auth: None · Cached: Edge cache with ETag
GET https://api.jiltv.app/v1/cosmetics/catalog/v1/cosmetics/twitchThe paint and badge that chatters wear, by Twitch login. Batch the visible chatters.
Auth: None · Cached: 1 minute
Parameters
logins queryComma-separated Twitch logins, at most 100.
GET https://api.jiltv.app/v1/cosmetics/twitch?logins=jilenceAccount
/v1/me/exportEverything JilTV stores about you, as one JSON file. Only works while signed in on the website.
Auth: Website session
GET https://api.jiltv.app/v1/me/exportGraphQL
/v1/graphqlQueries and mutations. See the API reference for every operation.
Auth: Optional
curl https://api.jiltv.app/v1/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"{ platformStats { emotes } }"}'/v1/graphql/schema.graphqlThe schema in SDL, for code generators.
Auth: None · Cached: 5 minutes
GET https://api.jiltv.app/v1/graphql/schema.graphqlStatus
/health/liveThe process is up.
Auth: None
GET https://api.jiltv.app/health/live/health/readyDatabase, cache and queue are reachable.
Auth: None
GET https://api.jiltv.app/health/readyUploading emotes
/v1/emotes Auth: EMOTES_WRITESend multipart/form-data with name (2–100 characters, no spaces), optional comma-separated tags,
an optional edit JSON and the file (PNG, GIF, WebP or JPEG, detected from the file content; up to 8 MB and 500
frames). Editors holding the UPLOAD permission can pass owner_id to upload in the name of the channel owner.
The API answers 202 with the emote in status PROCESSING. Poll emote(id:); it becomes ACTIVE within seconds with all sizes and formats generated.
curl https://api.jiltv.app/v1/emotes \
-H "Authorization: Bearer $JILTV_API_KEY" \
-F name=catDance \
-F tags=cat,dance \
-F 'edit={"crop":{"x":0,"y":0,"w":112,"h":112},"trim":true}' \
-F file=@cat.gifThe optional edit is applied server-side to every frame, in this order:
{
"frames": { "start": 0, "end": 20 }, // animations: keep these frames
"rotate": 90, // 0, 90, 180 or 270
"flip_h": true, "flip_v": false,
"crop": { "x": 0, "y": 0, "w": 112, "h": 112 }, // in source pixels
"key": { "color": "#00ff00", "tolerance": 30 }, // make a color transparent
"trim": true, // cut transparent borders (all frames)
"hue": 90, "grayscale": false, "invert": false, // like CSS hue-rotate/grayscale/invert
"shape": "circle", // or "rounded"
"reverse": false, "boomerang": true, // animations: play backwards / forth and back
"speed": 1.5 // animations: 0.25 to 4
}Uploads are limited to 20 per hour per account. Images larger than 4096 px (static) or 1024 px (animated) end in status FAILED, so scale them down before uploading.