Kick is the streaming platform most proxy guides mention in one line and never open. We opened it. On 28 September 2026 we fetched kick.com through residential exits in the United States, Germany and Brazil and from an ordinary home connection. The finding that shapes everything else: every channel page is a thin client over an 8,210-byte JSON object that any HTTP client can read, that Cloudflare caches for 15 seconds, and that answered 72 of 72 requests in a burst. The HTML page weighs 82 times as much and carries 63 words. And before you build anything on either, Kick's own terms forbid scraping, while its official public API is a real alternative that did not exist two years ago.
What Kick actually serves a proxied client
Kick is a Next.js application behind Cloudflare. A logged-out request for a channel URL comes back in three possible shapes, and they differ by two orders of magnitude in weight. We measured all three on the same channel, xQc, while it was live.
| Request | Status | Bytes (decoded) | Bytes on the wire | What it contains |
|---|---|---|---|---|
| /api/v2/channels/xqc (internal JSON) | 200 | 8,210 | 2,527 | Channel id, follower count (1,116,399), verified flag, social handles, live session with viewer count (9,172), category, chat settings |
| /api/v2/channels/xqc/livestream | 200 | 2,569 | 1,326 | The live session only, or an empty data object when offline |
| kick.com/xqc, plain HTTP, no JavaScript | 200 | 670,936 | 77,553 | Title, description, canonical, h1, 63 words; JSON-LD with ProfilePage, BroadcastEvent and an InteractionCounter holding the viewer count (9,090) |
| kick.com/xqc, rendered in a browser | 200 | 2,762,519 | n/a | 913 words: the channel panel, chat shell, recommended channels |
Three things stand out. First, the JSON endpoint is not hidden: it is what the page itself calls, and it answered a client sending a python-requests user agent from a home IP exactly as it answered a browser TLS fingerprint on a residential exit. Second, the server-rendered HTML is not empty. The seo_audit tool in our MCP server flagged most content as JavaScript-only (63 words without JavaScript against 913 rendered), but the structured data survives: the viewer count sits in the JSON-LD InteractionCounter before any script runs. The two viewer numbers differ by 82 because they were read seconds apart on a live stream. Third, rendering buys almost nothing a data job needs. The 913 rendered words are mostly recommendations and interface text.
One trap for anyone writing their own block detector: every HTML response embeds Cloudflare's challenge-platform script. Our own scraper classified the page as a challenge and retried it three times on each country before accepting it, although every response was a normal 200 with content. If your detector searches for that string, it will call every Kick page blocked; a WAF detector answers which firewall sits in front, which is a different question from whether this response was blocked. Check for the canonical link and the channel's h1 instead.
What the terms say, before the proxy question
Kick's Terms of Service prohibit reproducing the service by automated or non-automated scraping and using automated systems such as robots and spiders to access it. The developer terms go further and say an app must not be built for data scraping. Its robots.txt, by contrast, allows everything except browse and filter URLs (browse, languages=, sort=, tags=, clip=). That combination is common and it resolves one way: robots.txt tells crawlers where they are welcome, the terms are the contract, and the terms say no to scraping.
What that leaves, honestly, is a short list:
- The official public API. Kick launched a documented public API with OAuth app tokens. Its changelog lists channels by slug, livestreams with viewer counts, categories with viewer counts, and webhooks for livestream and moderation events. Called without a token it answers 401 Unauthorized in 37 bytes. If the question is "how many people are watching these 200 channels", this is the route that does not involve arguing with the terms.
- Checking what viewers in a market see. Brand and sponsorship teams verifying that a paid segment, a disclosure or a localized interface appears in a given country are reading one page as a person would, from that country. That is what a country-targeted proxy is for.
- Research at human scale on your own channels. Pulling your own channel's public numbers alongside your own analytics is a different thing from harvesting the platform.
What is not on the list, and what a large share of "kick proxy" searches are really about: viewer bots, follower inflation, and farms of accounts. Kick's community guidelines treat artificial engagement as a violation, and the top-ranking vendor guides for this keyword say plainly that inflated viewer counts get channels removed. No proxy changes that, because detection looks at behaviour, not at the IP. We do not help with it, and a proxy will not bring a banned channel back.
Which proxy type Kick really needs
The honest answer is: less than most guides sell you. The JSON endpoints are cached at Cloudflare's edge and did not gate on IP reputation in anything we sent, including a home connection with a scripted user agent. For reading public numbers at low volume, a datacenter proxy is the first thing to try, and at 2,527 bytes on the wire per channel lookup, bandwidth is almost free on any network. We did not test datacenter exits in this run, so treat that as the cheap first experiment, not a measured guarantee.
| Job | Proxy type | Why |
|---|---|---|
| Reading the official API | None, or any static IP | Authenticated by app token; the limit is the token, not the address |
| Checking the localized page from a country | Residential, country-targeted | Kick picks interface language from the exit country (see below); you need a real exit there |
| Watching streams from a market | Not a per-GB proxy job | Video is gigabytes per hour; at per-GB prices this is the most expensive thing you can do on Kick |
| Operating your own few accounts | One sticky residential or ISP IP per account | Stable address; rotation makes a logged-in session look hijacked |
Mobile proxies are not justified anywhere on this list. Nothing we measured behaved differently for a carrier IP, and Kick's web surface did not challenge residential traffic at all.
Geo-targeting: what changes by country
The clearest geo signal on Kick is in a response header. Each HTML response carries an x-middleware-rewrite that shows which internal route served it, and the route is keyed on the exit country:
| Exit | Internal route | HTML bytes | Channel JSON bytes |
|---|---|---|---|
| United States | /guest.US/en/xqc | 670,936 | 8,210 |
| Germany | /guest.DE/de/xqc | 688,750 | not fetched |
| Brazil | /guest.BR/pt/xqc | 683,416 | 8,210 |
So the page a guest sees is chosen by country: German interface strings from a German exit, Portuguese from a Brazilian one, with no cookie or Accept-Language involved. The JSON is the same object everywhere, served from a Cloudflare cache in Los Angeles for the US request and Sao Paulo for the Brazilian one. If your question is about data (followers, viewers, category), country does not matter. If it is about what a viewer in that market sees on the page, it is the whole point, and a residential exit in that country is the only way to see it.
The audience itself is not American by default. The livestream list endpoint, sorted by viewers, returned 24 streams: 9 in Spanish, 8 in English, 4 in Portuguese and one each in Japanese, Polish and Arabic. The top stream had 63,673 viewers, the 24th had 3,201. Anyone doing creator research on Kick should plan for Latin America before planning for the US.
Rate limits, caching and the error shapes
We sent 72 requests to the uncached livestream endpoint, 24 at a time, from a single IP. All 72 answered 200. A sequential pass over 24 different channels averaged 7,956 bytes and 1.66 seconds per call. We stopped there on purpose: the point was to find the shape of the limits at a polite volume, not to find the ceiling.
The more useful discovery is the cache policy, because it tells you how often polling is pointless:
| Endpoint | Cache-Control | Meaning for a poller |
|---|---|---|
| /api/v2/channels/{slug} | public, max-age=15 | Polling faster than every 15 seconds returns the same object from the edge |
| /api/v2/channels/{slug}/livestream | no-cache, private | Hits the origin every time; the one to rate-limit yourself on |
| /stream/livestreams/{lang} | public, max-age=60 | Once a minute is the useful ceiling |
| /api/v2/channels/{slug}/videos | public, max-age=14400 | Four hours; polling VODs hourly is waste |
And the error shapes we collected:
404 {"error":"Not Found","message":"Channel not found.","status":404} 65 bytes, cached 10 s
404 {"message":""} removed or unknown internal route
401 {"data":{},"message":"Unauthorized"} official API without a token
200 full HTML page containing the challenge-platform script not a block, see above
Note the difference between the two 404s. The first is a real answer about a channel; the second is an endpoint that no longer exists, which is what the old tutorials floating around GitHub now return. If your integration starts receiving the empty-message 404, the route moved, and no proxy will fix it. We did not see a 403 or a 429 in this run. On Cloudflare-fronted sites those arrive as HTML challenge pages rather than JSON, so the first check in any client is the content-type.
Cost math with real numbers
Prices from our pricing page: datacenter from $0.50/GB, residential from $0.80/GB, and the web scraping API from $0.0002 per page ($0.001 with rendering), billed only on success.
| Approach | Bytes per channel | Channels per GB | Cost per 1,000 channels |
|---|---|---|---|
| Channel JSON over residential ($0.80/GB) | 2,527 on the wire | about 395,000 | about $0.002 |
| HTML page, no JavaScript, residential | 77,553 on the wire | about 12,900 | about $0.06 |
| Rendered page, residential | 2,762,519 | about 360 | about $2.21 |
| Web scraping API, one page per channel | n/a | n/a | $0.20 |
| Web scraping API, livestream list (24 per call) | n/a | n/a | about $0.008 per 1,000 streams |
The per-channel byte figures exclude TLS and header overhead, so real consumption runs somewhat higher. The comparison still holds: rendering a Kick page to read a number that sits in an 8 KB JSON costs about a thousand times as much. At this weight, raw proxies are cheaper than any per-request API; what the API buys you is a browser-grade TLS fingerprint, retries and not paying for failures, which matters on sites that fight back and matters little on Kick's JSON.
There is no Kick collector in our catalogue, and given the terms we are not building one. For cross-platform creator research the sanctioned pieces are Kick's own API plus public data elsewhere, for example our YouTube channel collector. For how a comparable platform behaves, see what we measured on X through residential proxies, and for the general case of choosing between rotating and sticky exits, the rotating proxies page.
A practical checklist
- Start with the official API and an app token. If it covers your fields, you need no proxy at all.
- If you must read a page, read the JSON-LD in the server HTML (77 KB on the wire) before reaching for a browser (2.76 MB).
- Match your polling to the cache: 15 seconds for channels, 60 for lists, 4 hours for VODs.
- Use a country-targeted residential exit only when the question is what a viewer in that country sees.
- Treat the empty-message 404 as a moved route and the challenge-platform string as noise.
- Stay out of anything that inflates viewers, followers or chat. It breaks Kick's rules, it misleads sponsors, and it ends with the channel removed.