Kick All-in-One API
Pricing
from $11.70 / 1,000 live channel listings
Kick All-in-One API
Unofficial always-on REST API for live Kick.com data: home feed, live channel listings, search, channel profiles, real-time viewer counts, clips, VODs, playback URLs, and a Server-Sent Events endpoint for near-real-time chat. No account needed.
Pricing
from $11.70 / 1,000 live channel listings
Rating
0.0
(0)
Developer
Romy
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
7 days ago
Last modified
Categories
Share
What does Kick All-in-One API do?
Kick All-in-One API is a REST endpoint for Kick's live streaming data — home feed, browsable live-channel listings with real filters, full-text search, channel profiles, real-time (batched) viewer counts, clips, VODs, signed playback URLs, and chat. All from a single always-on API powered by Apify Standby.
It talks directly to the same internal APIs the official Kick Android app uses, reverse-engineered by capturing and analyzing live traffic from the real app. No Kick account, no API key — call the endpoint, get JSON back.
The standout endpoint is GET /channels/{id}/chat/stream — near-real-time chat delivered as Server-Sent Events, built on top of Kick's own REST-pollable chat history endpoint. No competing Kick scraper on Apify offers live chat at all.
Why use Kick All-in-One API?
- Live chat as Server-Sent Events — no WebSocket client needed on your end, no polling logic to write; connect once and receive new chat messages as they're posted
- Real, working filters everywhere they exist — confirmed live:
languageandcategory_idgenuinely filter/livestreams, and clips'sort/timegenuinely change results./home,/livestreams,/clips, and/categoriesall have real, confirmed-live pagination —/searchand/channels/{id}/videosdon't (see Data notes), and this README says so rather than papering over it - Batched real-time viewer counts — look up several channels' live viewer numbers in a single call
- Real, signed playback URLs — live, DVR, and VOD
.m3u8HLS manifests that actually play, not placeholder links - Always-on — Standby mode means no cold start, responds in milliseconds
- No account needed — every endpoint works fully anonymously
- Use cases: live-chat sentiment/moderation tooling, stream discovery bots, viewer-count/analytics dashboards, clip aggregation, esports/creator monitoring
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /home | Featured live channels, real-time viewer counts, paginated |
GET | /search | Full-text search: channels + categories + livestreams |
GET | /livestreams | Browsable live-channel listing, filterable & paginated |
GET | /categories | Every game/category, with live watcher counts, paginated |
GET | /viewers | Batched real-time viewer counts for multiple channels |
GET | /channels/{slug} | Merged channel profile (info + links + recent categories) |
GET | /channels/{slug}/leaderboard | Top gifters for a channel |
GET | /channels/{slug}/emotes | A channel's custom emote set |
GET | /channels/{id}/videos | A channel's saved VODs |
GET | /channels/{id}/videos/{videoId} | Full detail for one VOD |
GET | /clips | Popular/recent clips, site-wide or per-channel |
GET | /stream/{id}/playback | Real, signed HLS playback URLs (live/DVR/VOD) |
GET | /channels/{id}/chat/settings | Chat mode (slow mode, followers-only, etc.) |
GET | /channels/{id}/chat/history | Chat message history via plain REST polling |
GET | /channels/{id}/chat/stream | Near-real-time chat as Server-Sent Events |
How to use Kick All-in-One API
- Open this Actor's Standby API URL (shown on the Actor's page, under the API tab).
- Call any endpoint — for example:
Every call needs your Apify API token, either ascurl "https://romy--kick-all-in-one-api.apify.actor/home"curl "https://romy--kick-all-in-one-api.apify.actor/search?q=gaming"curl "https://romy--kick-all-in-one-api.apify.actor/livestreams?language=en&limit=10"curl "https://romy--kick-all-in-one-api.apify.actor/categories"curl "https://romy--kick-all-in-one-api.apify.actor/channels/kaneljoseph"curl "https://romy--kick-all-in-one-api.apify.actor/viewers?ids=123746987,124000001"curl "https://romy--kick-all-in-one-api.apify.actor/clips?sort=views&time=week"curl "https://romy--kick-all-in-one-api.apify.actor/channels/18750821/chat/history"# Server-Sent Events — stays open, streams new chat messages as they arrive:curl -N "https://romy--kick-all-in-one-api.apify.actor/channels/18750821/chat/stream"Authorization: Bearer <token>or?token=<token>— the Actor's page API tab has a ready-to-copy version with your token filled in. - Read the JSON response (or, for
/chat/stream, the SSEdata:event stream) — no setup required.
Parameters
GET /home — no required parameters. page optional (int, default 1) — real pagination, confirmed live: 14 channels per page, distinct pages return distinct, non-overlapping channels.
GET /categories — no required parameters. limit (int, default 32) and page (int, default 1) optional — real pagination, confirmed live: distinct pages return distinct category ids.
GET /search — q required.
GET /livestreams
| Param | Type | Example | Meaning |
|---|---|---|---|
sort | enum, default viewer_count_desc | viewer_count_desc | viewer_count_desc | featured |
language | string | en | ISO 639-1 — confirmed live to filter results |
category_id | integer | 15 | From GET /categories |
limit | int, default 24 | 24 | |
cursor | string | From the previous response's results.data.pagination.next_cursor |
GET /viewers — ids required (comma-separated livestream ids, from GET /livestreams or GET /home).
GET /channels/{slug} — path param slug required (e.g. kaneljoseph). Response includes the channel's numeric id, required by every endpoint below.
GET /channels/{id}/videos — path param id required (numeric channel id, not slug). No parameters — confirmed live this endpoint has no pagination of any kind (see Data notes) and always returns the same up-to-30 most recent VODs.
GET /clips
| Param | Type | Example | Meaning |
|---|---|---|---|
sort | enum, default views | views | views | date |
time | enum, default week | week | day | week | month | all |
channel_id | integer | 18750821 | Omit for site-wide clips, from GET /channels/{slug} |
cursor | string | From the previous response's results.data.cursor |
GET /stream/{id}/playback — path param id required (a livestream or VOD id, from GET /livestreams, GET /home, or GET /channels/{id}/videos).
GET /channels/{id}/chat/history — path param id required (numeric channel id). start_time optional (ISO 8601, defaults to now).
GET /channels/{id}/chat/stream — path param id required (numeric channel id).
| Param | Type | Example | Meaning |
|---|---|---|---|
start_time | string (date-time) | ISO 8601 — defaults to now | |
interval_ms | int, default 3000, min 1000 | 3000 | How often this Actor polls Kick internally |
Output
Every non-SSE response is returned directly over HTTP — this Actor does not write to an Apify dataset. Real responses (trimmed for readability):
GET /channels/kaneljoseph:
{"success": true,"channel": {"id": 18750821,"slug": "kaneljoseph","chatroomId": 18490228,"info": { "verified": true, "followers_count": 89833, "livestream": null },"links": [],"recentCategories": [{ "name": "IRL", "viewers": 202259 }]}}
GET /viewers?ids=123746987:
{ "success": true, "results": [{ "livestream_id": 123746987, "viewers": 39318, "show_view_count": true }] }
GET /clips?sort=views&time=week (trimmed to one clip):
{"success": true,"results": {"data": {"clips": [{"id": "clip_01M060TASC2P5DEWRA1V3HNTZ2","title": "...","channel": { "slug": "maherco", "username": "Maherco", "is_verified": true },"views_count": 58900,"playback_url": "https://clips.kick.com/clips/87/clip_01M060TASC2P5DEWRA1V3HNTZ2/playlist.m3u8"}]}}}
GET /channels/18750821/chat/stream (Server-Sent Events, one data: line per new message batch):
data: [{"id":"c62e3b2d-...","chat_id":4351775,"content":"...","sender":{"username":"3sam55","identity":{"badges":[{"type":"subscriber"}]}},"created_at":"2026-08-23T22:48:30Z"}]data: [{"id":"98d5b55e-...","chat_id":4351775,"content":"[emote:37226:KEKW]","sender":{"username":"arwa22110"},"created_at":"2026-08-23T22:48:34Z"}]
Data notes
- No signature or token required anywhere, confirmed live across all four API hosts this Actor calls (
kick.com,mobile.kick.com,search.kick.com, plus the.m3u8playback hosts) — every request needs nothing but a plain, static identity header set. Independently re-confirmed by calling every endpoint directly from a plain server, no device involved. - The official viewer app wasn't surfaced by an in-app Play Store search on the research device (a device-compatibility filter, not a real absence) — the APK (
com.kick.mobile) was sideloaded directly for this research. Kick's other Play Store app, "KICK - Go Live" (com.kick.streaming), is a separate broadcaster tool for going live from a phone camera, not a viewer app, and wraps none of the data this Actor exposes. - Two id systems are used inconsistently by Kick's own app, and this Actor stays faithful to that.
kick.com-hosted endpoints (/channels/{slug},/channels/{slug}/leaderboard,/channels/{slug}/emotes,/current-viewers) take a channel'sslug.mobile.kick.com-hosted endpoints (videos, clips-per-channel, chat) take its numericidinstead — confirmed live, passing a slug there fails.GET /channels/{slug}returns both so callers can chain without guessing. /stream/{id}/playbackneeds a request body, confirmed live. The real app sends a large payload of player/session/ad-SDK telemetry; a bare POST gets rejected with400 Bad Request. This Actor sends a trimmed version with only the fields confirmed necessary (player name/version, connection type, a placeholder device/session id) — confirmed live this still returns real, playable signed URLs./clipsand/livestreamsboth use real cursor-based pagination, not page numbers — confirmed live through this Actor's own routes: paging with the previous response's cursor returned a second batch with zero id overlap against the first, for both endpoints. The cursor lives in a different spot in each response shape (results.data.cursorfor clips,results.data.pagination.next_cursorfor livestreams) — this Actor exposes both as-is rather than normalizing them, so pass whichever one straight through as this endpoint'scursorparam, don't attempt to decode or construct it yourself./livestreams'languageandcategory_idfilters were confirmed live by testing values directly against the API, not just observed in the app UI — a request withlanguage=frreturned livestreams with"language":"fr"in every result, and unrecognized param names were silently ignored (confirming these exact names, not near-misses, are what the backend actually reads)./livestreams'sortis a strictly-validated required enum, unlike most other params here — confirmed live: an empty, missing, or nonsensesortvalue gets a real400 Invalid requestfrom Kick's own backend, not a silent fallback. This Actor always sends a valid value (viewer_count_descby default), so callers never need to worry about this./homeis genuinely paginated, confirmed live — 14 channels per page,page=2andpage=3each returned a fully distinct set of channel ids with zero overlap against page 1./channels/{id}/videoshas no pagination at all, confirmed live by testing every plausible param name (page,cursor,after,offset, andlimit) directly against the API — every one was silently ignored, always returning the identical up-to-30 most recent VODs. This is a real backend limitation, not a gap in this Actor./searchis capped at 3 results per category (channels/categories/livestreams) with no pagination, confirmed live the same way —limit,page, andoffsetwere all tried directly against the API with zero effect on result count. Treat it as quick suggestions, not an exhaustive search; for a full channel/category listing use/livestreamsor/categoriesinstead./channels/{id}/chat/streamis this Actor's own construction, not a single upstream endpoint. It pollsGET /channels/{id}/chat/historyon an interval (default 3s) and forwards each new, non-empty batch as one Server-Sent Event, de-duplicating by message id across polls. Confirmed live against a channel with active chat: two polls 3 seconds apart delivered two batches with zero overlapping message ids. Billing reflects this — you're charged per delivered message batch, not per second connected, so holding the connection open on a quiet or offline channel costs nothing.- A real WebSocket endpoint (
websockets.kick.com/viewer/v1/token) also exists for true push-based chat, confirmed live in the app's own traffic, but is not used here — the REST-polling approach above needs no token exchange or persistent socket management on either side, at the cost of up tointerval_msof latency versus true push.
Pricing
Pay-per-event, billed on each successful call (or, for /channels/{id}/chat/stream, on each delivered message batch). See the Actor's Pricing tab for current rates.
Known limitations
- No booking/checkout-equivalent endpoints — there is no purchase flow on Kick to wrap, but for the same reason as every other actor in this family: this Actor only wraps guest-accessible, read-only endpoints. No login flow (sending chat messages, following, gifting, subscribing) is implemented or planned, by design.
/channels/{id}/chat/streamlatency is bounded byinterval_ms(default 3s, minimum 1s) — this is REST-polling dressed as a stream, not the app's own WebSocket push channel, so expect up to that much delay versus watching chat live in the app itself.- This is an unofficial, reverse-engineered integration, not affiliated with or endorsed by Kick Streaming, Inc. Behavior may change if Kick changes its API.
Found a bug or have a feature request? Use the Issues tab on this Actor's page.