RTFC API

Streaming results

Results arrive over Server-Sent Events as research finishes, rather than you polling for them.

Connect

Server-side, with a header:

bash
curl -N "$RTFC/stream?debate_id=$DEBATE" -H "X-Auth-Token: $TOKEN"

From a browser - EventSource cannot send headers, so mint a short-lived stream token server-side and pass it in the query string:

bash
curl -sX POST $RTFC/stream/token -H "X-Auth-Token: $TOKEN"
# {"stream_token": "…"}
js
const es = new EventSource(`${RTFC}/stream?token=${streamToken}&debate_id=${debateId}`);

A stream token lasts 5 minutes and works only for the stream endpoints - it is rejected as a general bearer token, so putting it in a URL risks far less than a PAT would.

The event contract

Events are JSON on the data: line. RTFC never sets the SSE event: field - switch on the type property in the payload:

data: {"type":"ping"}

data: {"type":"new_claim","claim_id":"…","claim_text":"…","debate_id":"…"}

data: {"type":"result","claim_id":"…","query_id":"…","verdict":"false","confidence":0.97, …}
typeMeaning
pingKeepalive, every 20s. Ignore it.
new_claimA claim was detected. Show a pending card.
resultA panel finished.
claim_completeEvery expected method finished for a claim; carries the best answer.

Ignore any type you do not recognise - new ones may appear.

A result event carries cost_usd for that panel and claim_total_cost_usd for the claim so far, so you can meter without a second request.

Per-claim progress

GET /v1/stream/claim/{claim_id} streams one claim's research progress - search steps, documents fetched - and closes on the verdict. Useful for a detail view where showing work reduces perceived latency.

Reconnecting

The connection can drop; treat that as normal. EventSource reconnects on its own, but your token may have expired - mint a new one and reopen. Nothing is lost: GET /v1/claims/{id}/results always has the current state, so reconcile on reconnect rather than assuming you saw every event.

If holding a connection is awkward - a mobile app that gets backgrounded, a serverless backend - use webhooks instead.