API docs
Search docs
Guides, operations and types

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

GET /v1/channels/{platform}/{channelId}/bootstrap

The 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 path

twitch, kick or youtube

channelId path

The channel ID on the platform, e.g. the numeric Twitch user ID.

Request
GET https://api.jiltv.app/v1/channels/twitch/123456/bootstrap
GET /v1/sets/global

Global emote sets, available in every channel.

Auth: None · Cached: Edge cache with ETag

Request
GET https://api.jiltv.app/v1/sets/global
GET /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 path

Twitch login name, lowercase.

Request
GET https://api.jiltv.app/v1/resolve/twitch/jilence
GET /v1/personal-emotes/twitch

Personal 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 query

Comma-separated Twitch logins, at most 100.

Request
GET https://api.jiltv.app/v1/personal-emotes/twitch?logins=jilence
GET /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

Example
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

GET /v1/cosmetics/catalog

Every published paint and badge with its design. Cache it; users only reference cosmetics by ID.

Auth: None · Cached: Edge cache with ETag

Request
GET https://api.jiltv.app/v1/cosmetics/catalog
GET /v1/cosmetics/twitch

The paint and badge that chatters wear, by Twitch login. Batch the visible chatters.

Auth: None · Cached: 1 minute

Parameters

logins query

Comma-separated Twitch logins, at most 100.

Request
GET https://api.jiltv.app/v1/cosmetics/twitch?logins=jilence

Account

GET /v1/me/export

Everything JilTV stores about you, as one JSON file. Only works while signed in on the website.

Auth: Website session

Request
GET https://api.jiltv.app/v1/me/export

GraphQL

POST /v1/graphql

Queries and mutations. See the API reference for every operation.

Auth: Optional

Example
curl https://api.jiltv.app/v1/graphql \
  -H 'Content-Type: application/json' \
  -d '{"query":"{ platformStats { emotes } }"}'
GET /v1/graphql/schema.graphql

The schema in SDL, for code generators.

Auth: None · Cached: 5 minutes

Request
GET https://api.jiltv.app/v1/graphql/schema.graphql

Status

GET /health/live

The process is up.

Auth: None

Request
GET https://api.jiltv.app/health/live
GET /health/ready

Database, cache and queue are reachable.

Auth: None

Request
GET https://api.jiltv.app/health/ready

Uploading emotes

POST/v1/emotes Auth: EMOTES_WRITE

Send 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.gif

The optional edit is applied server-side to every frame, in this order:

edit
{
  "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.

Search
Find emotes or jump to a page