How to Fix SSE Stream Problems (ER0360, Disconnects)
A silent stream, a connection limit that will not clear, ordering surprises and expected disconnects — with the exact error codes
Written by Erick Horn
July 6, 2026
How to fix SSE stream problems (ER0360, disconnects)
Most SSE stream problems fall into three buckets, each with a fast fix: a stream that connects but stays silent (usually filters that match nothing new), a 429 with code ER0360 because your plan’s connection slots are taken — clearable with DELETE /v1/news/stream/sessions — and disconnects that are actually by design, like the 6-hour session limit (ER0362). This guide walks each bucket with the exact behaviour of /v1/news/stream, so you fix the real cause instead of blindly reconnecting.
Why is my stream connected but silent?
A connected stream that sends nothing is usually working exactly as designed. The stream delivers new articles only: on connect it anchors to the latest matching article and pushes what is indexed after that moment. It checks for new matches about every 30 seconds and sends up to 50 articles per cycle — so with narrow filters, minutes of silence are normal. The : heartbeat lines you see every ~30 seconds are comments keeping the connection alive, not events, and they cost nothing.
To confirm the filters are the issue, run them against the search endpoint — the stream accepts the same dot-notation parameters as /v1/news/everything:
curl "https://api.apitube.io/v1/news/everything?title=acme&language.code=en&api_key=YOUR_API_KEY"
Few or zero results there means few or zero stream events. Widen one filter at a time, as in debugging an empty search. Also check which key you connected with: a test key streams events with masked content — if you filter on the masked text downstream, everything looks empty.
How do I fix “Maximum SSE connections” (ER0360)?
HTTP 429 with ER0360 means every simultaneous-connection slot your plan allows is occupied. Slots are counted per account owner: Basic allows 2, Professional 10, Corporate 50, and the Free plan has no streaming at all. A cleanly closed stream frees its slot immediately — but a client that crashed or lost network without closing the socket can leave the slot occupied until the server notices the dead connection, which can take a few minutes.
You do not have to wait. Two management endpoints exist exactly for this, and neither costs credits:
# See which sessions are holding your slots
curl "https://api.apitube.io/v1/news/stream/sessions" -H "X-API-Key: YOUR_API_KEY"
# Free them all (or one: ?session_id=..., or per key: ?api_key_id=...)
curl -X DELETE "https://api.apitube.io/v1/news/stream/sessions" -H "X-API-Key: YOUR_API_KEY"
GET lists each active session’s session_id, api_key_id and started_at — a session that started hours ago from a process you already killed is your zombie. DELETE force-closes the sessions (the closed streams receive an error event with code ER0364), and the slots are free for your next connect. Calling DELETE before a planned restart of your consumer is the clean way to avoid ER0360 entirely.
Why did my stream disconnect?
Some disconnects are planned, and the error code tells you which one you got:
ER0362— a single session may live at most 6 hours; the server asks you to reconnect. Reconnect with theLast-Event-Idheader set to the last article id you received and you miss nothing.ER0301— your balance ran out mid-stream. Top up or wait for plan credits to renew, then reconnect.ER0361— the API key was revoked while streaming; the session ends immediately.ER0364— the session was terminated viaDELETE /v1/news/stream/sessions(see above).
A drop with no error event is plain network trouble. The browser EventSource reconnects and replays Last-Event-Id automatically; a custom client should do the same — the resume recipe is in how to stream news with SSE.
Why do articles arrive late or out of order?
The stream follows the indexing order, not the publication order: its cursor moves over article ids, and each batch is sorted by published_at before it is written to you. An article published an hour ago but crawled just now still arrives — with its original published_at in the payload. So “real time” means as articles enter the index, which is worth knowing before you alert on timestamps; how fresh the data is covers the pipeline latency itself.
If stale-looking articles are noise for your use case, cut them at the server with stream.max_age — the maximum age, in minutes, an article’s publication date may have to be delivered:
curl -N -H "X-API-Key: YOUR_API_KEY" \
"https://api.apitube.io/v1/news/stream?language.code=en&stream.max_age=60"
stream.max_age must be a positive whole number of minutes; anything else is rejected with 400 and code ER0363.
Do parallel streams multiply my bill?
Yes. Each connection is billed independently, one credit per article it delivers — three identical streams receiving the same article spend three credits. Slots and billing are separate concerns: even within your slot limit, duplicate streams are pure overhead. Run one stream per filter set and fan the events out to consumers inside your own infrastructure; if different teams need different filters, narrow each stream so their results do not overlap.
Common Questions
- Do heartbeats or the open connection cost credits?
- Can I resume after the 6-hour disconnect without losing articles?
- Does closing a stream free the slot instantly?
- Why was my connection rejected with ER0176?
Do heartbeats or the open connection cost credits?
No. You pay one credit per article actually delivered, drawn from the streaming credit pool. Heartbeat comments, the idle connection, and the GET/DELETE session-management endpoints are all free.
Can I resume after the 6-hour disconnect without losing articles?
Yes. Keep the id: of the last article event you processed and send it as the Last-Event-Id header on reconnect — APITube delivers everything that matched after that id, then continues live. The 6-hour limit (ER0362) costs you a reconnect, never data.
Does closing a stream free the slot instantly?
A clean close does — the moment the socket closes, the slot is back. Only an unclean drop (crash, dead network path) leaves a slot occupied until the server detects the dead socket. If you hit ER0360 after a crash, clear the zombie with DELETE /v1/news/stream/sessions instead of waiting.
Why was my connection rejected with ER0176?
402 with ER0176 means the account has no streaming credits and no positive pay-as-you-go balance — the connection is refused before it opens. This is different from ER0301, which ends a stream that ran out of balance mid-flight. Check the streaming pool on your dashboard’s usage page and see what counts as a request for how the pools are spent.