RTFC API

Checking a video, a stream, or a file

Always probe first

bash
curl -sX POST $RTFC/media/probe -H "X-Auth-Token: $TOKEN" \
  -H 'Content-Type: application/json' -d '{"url": "https://…"}'

Anonymous, synchronous, creates nothing, costs nothing. YouTube, TikTok and Instagram are supported.

"Public" means an anonymous fetch succeeds. Every probe is made without cookies, deliberately - a video that only downloads because our servers happen to be signed in somewhere is not public, and treating it as such would leak private content between accounts.

reject_reasonMeaning
unsupported_platformNot a platform we can fetch
not_a_single_videoA playlist, channel or profile
unavailableDeleted, or the id is wrong
privateNot publicly viewable
needs_authRequires a login
geo_blockedNot available from our region
live_in_progressStill streaming - try again when it ends

Empty means it is usable.

Ingest

bash
curl -sX POST $RTFC/debates/$DEBATE/upload-media \
  -H "X-Auth-Token: $TOKEN" -H 'Content-Type: application/json' \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"url": "https://…", "language": "auto", "detector_mode": "batch"}'

For YouTube, the video's own captions are used when available - no transcription cost, exact timestamps - falling back to audio + speech-to-text automatically when there are none in the language you asked for.

detector_mode:

claim quality on recorded material. Use this for uploaded video.

Audio files and live audio

POST /v1/debates/{id}/upload-audio takes a file (multipart file, plus optional whisper_provider, language, no_diarize). no_diarize skips speaker separation - much faster, at the cost of not knowing who said what.

For live audio, POST /v1/session/start spawns a listener, then POST /v1/session/audio-ingest-token gives you a short-lived WebSocket URL to stream into.

That token call returns 409 while the listener is still starting. That is expected and retryable - poll it, do not treat it as an error.

Positions in the video

Each claim carries media_offset_ms: where in the media it was said, measured from the start of the media rather than wall-clock. That is what you need to sync verdicts to a player's current time.

It is null when the position could not be determined - never 0 as a stand-in, so a falsy check is safe.

Reuse

If a public analysis of the same video already exists, use it instead of paying to redo it - see the tutorial. The reused analysis is a normal debate you have been granted access to, so every ordinary endpoint works on it unchanged.