Twitch All-in-One API
Pricing
from $0.94 / 1,000 channel profiles
Twitch All-in-One API
Unofficial always-on REST API for live Twitch data: channels, live streams, search, categories, VODs, clips, VOD chat archive, teams, emotes and badges. No account, app or device needed.
Pricing
from $0.94 / 1,000 channel profiles
Rating
0.0
(0)
Developer
Romy
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
Unofficial, always-on REST API for live Twitch data: channels, live streams,
search, categories, VODs, clips, VOD chat archive, teams, emotes and badges.
Wraps Twitch's own public web GraphQL API (gql.twitch.tv), verified live
against the real API — including from Apify's own IPs. No account, login,
app or device needed for any endpoint here.
Why
Twitch's own web client talks to gql.twitch.tv with a public client id
that every anonymous visitor sends — no login, no signing. Every parameter
below was live-tested and classified as a real filter, a shaping/ordering
flag, or inert (accepted but ignored) before being exposed here.
- Pagination is honest. Twitch's cursor pagination (
after) on most list connections (streams, videos, clips) requires a device-attestation token this API cannot obtain — every affected endpoint here is a single page (first, up to 100), clearly documented, not a silent lie about crawling a full catalog. The one genuine exception is/teams/:name/members, which has real working cursor pagination, and/videos/:id/chat, which sidesteps the limit entirely by seeking through a VOD by timestamp instead of a cursor. - VOD chat archive is the standout feature: walks a VOD's full chat log (commenter, message, emotes, badges, color) from any starting second, verified end-to-end across a 5.5-hour VOD.
- Dead/inert fields are left out. Twitch's schema still has old fields
(
stream.tags,topTags, raid/host data) that no longer return real data since product changes — this API exposes the field that actually works (freeformTags) instead of a field that always returns nothing. - What isn't anonymously available and isn't promised here: who a channel follows, subscriber lists/counts, active polls or predictions, moderator/VIP lists, stream markers, and hosting/raids (Twitch removed Host Mode in 2022). These need a real logged-in user token Twitch does not grant anonymously; this API does not fake or guess at them.
Endpoints
Channels
GET /channels/:login
Channel/user profile: bio, profile image, banner, creation date, partner/affiliate status, follower count, primary team, plus embedded live stream info (title, game, viewersCount, startedAt, thumbnailUrl, freeformTags) if currently live. profileViewCount is included but is confirmed to always be null upstream -- Twitch no longer populates it. Returns 0 items for an unknown login (upstream returns null, not an error).
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
Billed per item returned (get-channel event); an empty result is free.
GET /search
Twitch search (searchFor). target selects the index: CHANNEL, GAME, or VOD -- the only 3 SearchIndex values confirmed valid (CATEGORY/CLIP/CLIPS/VIDEO confirmed invalid). Results are confirmed relevance-ranked per query text.
| Param | Required | Description |
|---|---|---|
q | yes | Search text. |
target | no | What to search: CHANNEL (channels/users), GAME (games/categories), or VOD (past broadcasts). Default CHANNEL. Only these 3 SearchIndex values are confirmed valid upstream -- CATEGORY/CLIP/CLIPS/VIDEO were live-tested and confirmed invalid. (one of CHANNEL, GAME, VOD) |
first | no | Number of results to return, 1-100 (default 10). Confirmed honored exactly at 50 and 100 in testing; no cap found up to 100. |
Billed per item returned (search event); an empty result is free.
GET /streams
Top live streams, either the global front page (default, Twitch's own front-page listing sorted by viewersCount descending) or scoped to one game. sort (StreamSort) only applies when game is set. The tags filter available on this upstream connection is confirmed INERT (identical results with/without it) and is deliberately not exposed here.
| Param | Required | Description |
|---|---|---|
game | no | Restrict to one game/category (exact name, e.g. "Just Chatting"). Omit for the global front-page top streams. An unknown game name returns zero results rather than an error (confirmed upstream behaviour). |
sort | no | Stream ordering (StreamSort enum) -- only applies when game is set; each of these 4 values was confirmed live to produce a distinct, meaningfully different order. Ignored for the global front-page listing (game omitted), which was only ever verified as viewersCount descending. (one of VIEWER_COUNT, VIEWER_COUNT_ASC, RECENT, RELEVANCE) |
first | no | Number of streams to return, 1-100 (default 20). This endpoint can only return one page: Twitch's cursor pagination requires a device-attestation token the public API does not grant. |
Billed per item returned (top-streams event); an empty result is free.
GET /games
Twitch's Browse-page games/categories directory, sorted by live viewer count descending.
| Param | Required | Description |
|---|---|---|
first | no | Number of games to return, 1-100 (default 20). This endpoint can only return one page: Twitch's cursor pagination requires a device-attestation token the public API does not grant. |
Billed per item returned (top-games event); an empty result is free.
GET /channels/:login/tags
A currently-live channel's real freeform stream tags (freeformTags), the ones actually shown in Twitch's UI. The legacy tags field is confirmed dead (always empty) and is deliberately not exposed. Returns 0 items if the channel is offline or unknown to Twitch (both confirmed, non-error upstream states).
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
Billed per item returned (channel-tags event); an empty result is free.
GET /channels/:login/schedule
A channel's published upcoming broadcast schedule segments (id, title, startAt, endAt). Many channels don't publish one at all -- confirmed upstream as either schedule: null or schedule.segments: null, both mapped here to 0 items rather than an error, same as an unknown login.
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
Billed per item returned (schedule event); an empty result is free.
Videos
GET /videos
One page of a channel's videos/VODs (up to 100, newest-first by default). Twitch's cursor pagination (after) is rejected with an integrity-check error requiring a device-attestation token this API does not have -- so this endpoint returns a single page only, sized by first (server max 100). A channel with more than 100 matching videos cannot have the rest listed.
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
first | no | Number of videos to return, 1-100 (default 20). This endpoint can only return one page: Twitch's cursor pagination requires a device-attestation token the public API does not grant. |
sort | no | Sort order for the video list: TIME (default, newest first) or VIEWS (highest view count first). Confirmed to genuinely reorder results. (one of TIME, VIEWS) |
type | no | Filter by broadcast type: ARCHIVE (past live broadcasts), HIGHLIGHT (creator-curated highlights), or UPLOAD (direct uploads). Confirmed genuine filter -- every returned video matches the requested type. (one of ARCHIVE, HIGHLIGHT, UPLOAD) |
Billed per item returned (list-videos event); an empty result is free.
GET /videos/:id
Full detail for one VOD: title, description, duration, view count, and per-segment game/chapter markers (chapters, from momentRequestType: VIDEO_CHAPTER_MARKERS) for multi-game broadcasts. Resolution/quality list and muted-segment info are not exposed by this query (open gaps -- see the source contract) and are omitted rather than guessed.
| Param | Required | Description |
|---|---|---|
id | yes | Twitch video/VOD numeric id (as seen in a twitch.tv/videos/ |
Billed per item returned (video-detail event); an empty result is free.
GET /clips
One page of a channel's top clips (up to 100), optionally windowed by period. Same pagination caveat as /videos: after is integrity-gated, so this is a single page sized by first (max 100).
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
first | no | Number of clips to return, 1-100 (default 20). This endpoint can only return one page: Twitch's cursor pagination requires a device-attestation token the public API does not grant. |
period | no | Time window for the top-clips ranking (default ALL_TIME). Confirmed genuine filter: each period returns a distinct, date-bounded set of clips with different view counts. (one of LAST_DAY, LAST_WEEK, LAST_MONTH, ALL_TIME) |
Billed per item returned (list-clips event); an empty result is free.
GET /clips/:slug
Full detail for one clip, including per-quality direct MP4 download URLs (videoQualities) and the offset (videoOffsetSeconds) into its source VOD.
| Param | Required | Description |
|---|---|---|
slug | yes | Twitch clip slug (from a /clips list result -- never guessed). |
Billed per item returned (clip-detail event); an empty result is free.
GET /videos/:id/chat
Replays a VOD's chat log by seeking forward with contentOffsetSeconds instead of cursor pagination -- unlike every other list endpoint in this API, this is NOT integrity-gated and is confirmed walkable end-to-end across an entire VOD (verified offset 0 through 20050 on a 20,056s VOD, no blocker hit). Each message carries its VOD offset, the commenter, message text broken into fragments with any emote references, chat badges, and name color. Commenter logins are Twitch's own public usernames, the same ones visible in the platform's live/VOD chat -- not additional PII, though archiving them at scale is a different exposure profile than one-off viewing. To read a whole long VOD, keep calling with startSeconds set to the previous response's nextOffsetSeconds until it comes back null.
| Param | Required | Description |
|---|---|---|
id | yes | Twitch video/VOD numeric id (as seen in a twitch.tv/videos/ |
startSeconds | no | VOD offset (seconds) to start walking chat from (default 0). To page through a long VOD, pass the previous call's nextOffsetSeconds back in here. |
maxMessages | no | Max chat messages to walk and return in this single call (default 500, max 5000). Caps how many upstream page-fetches one request can make so it can never run forever or hammer Twitch; a caller wanting a whole long VOD's chat should keep calling with startSeconds set to the returned nextOffsetSeconds until it comes back null. |
Billed per item returned (vod-chat-message event); an empty result is free.
Social
GET /channels/:login/followers/count
Live follower count for a channel. The follower LIST is not available: Twitch's API resolves an always-empty edges array for it (verified, not an auth error) while still resolving this same totalCount field -- so only the count is exposed here, deliberately.
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
Billed once per successful request (follower-count event).
GET /teams/:name
A Twitch team's profile: id, name, display name, description and banner/logo image URLs.
| Param | Required | Description |
|---|---|---|
name | yes | Twitch team name (the part after twitch.tv/team/, lowercase). |
Billed once per successful request (team event).
GET /teams/:name/members
One page of a Twitch team's member roster. This is the one list endpoint in this whole API with genuine working cursor pagination (verified: after advances exactly first positions forward, no overlap/gap) -- it is not subject to the IntegrityCheckFailed device-attestation wall most other list endpoints hit. Pass the returned nextCursor back as after to fetch the next page; hasNextPage: false or a missing nextCursor means the roster is exhausted.
| Param | Required | Description |
|---|---|---|
name | yes | Twitch team name (the part after twitch.tv/team/, lowercase). |
first | no | Number of members to return, 1-100 (default 100). Unlike most list endpoints on this API, this one has genuine, verified working cursor pagination -- see after. |
after | no | Opaque pagination cursor from a previous page's nextCursor. Omit to fetch the first page. |
Billed per item returned (team-members event); an empty result is free.
GET /channels/:login/subscription-products
A channel's paid subscription tiers: display name, tier code, price and per-tier emote set. This is tier/pricing metadata, NOT a subscriber count or list -- no subscriber count or list field exists anonymously anywhere in this API.
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
Billed per item returned (subscription-products event); an empty result is free.
GET /channels/:login/emotes
All of a channel's anonymously-public emotes in one call: subscriber emotes (per tier), follower/local emotes, and cheermote name prefixes. Subscriber and follower/local items include a resolvable cdnUrl built from the verified static CDN URL pattern (not a GraphQL field). Cheermote items only expose id (the name prefix, e.g. "Cheer"/"Kappa") -- per-tier bit thresholds/colors/images were not part of the verified contract, so no cdnUrl is claimed for them.
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
Billed per item returned (channel-emotes event); an empty result is free.
GET /channels/:login/badges
A channel's subscriber-month chat badge set: title, description and an image URL at the requested resolution. Each badge also exposes idDecoded, the raw base64-decoded id string -- see the field note in the response for why any numeric pattern inside it is not treated as a documented tenure code.
| Param | Required | Description |
|---|---|---|
login | yes | Twitch channel login (the part after twitch.tv/, lowercase, not the display name). |
size | no | Badge image resolution: NORMAL (1x), DOUBLE (2x, default), QUADRUPLE (4x). SMALL/LARGE are real values that were tried and rejected upstream ("Value does not exist in BadgeImageSize enum") -- not offered here. (one of NORMAL, DOUBLE, QUADRUPLE) |
Billed per item returned (channel-badges event); an empty result is free.
Pricing
Pay-per-event (PPE), tiered by Apify plan (FREE/BRONZE/SILVER/GOLD/PLATINUM/DIAMOND = 100/92/85/78/72/68% of the FREE price). See the Actor's Pricing tab for exact current prices.
Known limitations
- Most list endpoints (
/streams,/games,/videos,/clips,/search) return one page only (first, up to 100) — see "Why" above. /videos/:id/chatcaps how many messages a single call walks (maxMessages); page a long VOD by passing the previous call'snextOffsetSecondsback in asstartSeconds./channels/:login/followers/countreturns a count only — Twitch does not expose the follower list anonymously, by design./channels/:login/subscription-productsreturns tiers/prices/emotes, not a subscriber list or count, which does not exist in the public schema.
Getting started
npm installnpm run start:dev