Overshoot quickstart for live video inference
This quickstart covers one complete Overshoot session: list models, create a /v1beta Stream, publish WebRTC video through LiveKit, query the latest frame, read SSE output, renew the 300-second lease, and delete the Stream. Active Streams retain 600 seconds. Keep the API key on a trusted server and send only short-lived LiveKit credentials to browser code.
- API version
- /v1betaBase path for Streams, models, and chat completions.
- Stream operations
- 4Create, inspect, keep alive, and delete.
- Lease
- 300 secondsA keepalive renews the lease and supplies a fresh LiveKit token.
- History
- 600 secondsRolling frame history exposed through ovs:// references.
- Streaming
- SSESet stream to true for incremental chat-completion output.
Prepare authentication and choose a model
Set OVERSHOOT_API_KEY on your server and use Authorization: Bearer for protected requests. Call GET /v1beta/models, choose a record whose status is ready, and keep its id verbatim. Do not expose an organization key through a VITE-prefixed variable. Test the chosen model with the media type and optional features you need.
List models
curl https://api.overshoot.ai/v1beta/models
Create the leased Stream
POST /v1beta/streams with an empty body and bearer authentication. Save id, publish.url, publish.token, expires_at_ms, and ttl_seconds. The lease is 300 seconds. Creation opens the session but adds no frames. A publisher must join the returned LiveKit room and send a video track before inference can resolve Stream media.
Create Stream request
curl -X POST https://api.overshoot.ai/v1beta/streams \
-H "Authorization: Bearer $OVERSHOOT_API_KEY"
Publish one browser video track
Request a camera MediaStream, connect a LiveKit Room with publish.url and publish.token, and publish the video track. Live ingest is WebRTC through LiveKit. Handle permission denial and track ending, and stop local tracks on exit. Before inference, use GET /v1beta/streams/{stream_id} to confirm that recent frames exist.
Publish with LiveKit
const media = await navigator.mediaDevices.getUserMedia({ video: true })
const room = new Room()
await room.connect(stream.publish.url, stream.publish.token)
await room.localParticipant.publishTrack(media.getVideoTracks()[0])
Query the latest frame and read SSE
POST /v1beta/chat/completions with a ready model, text, the latest-frame image_url, stream=true, and a small max_completion_tokens value. Decode response.body incrementally, preserve incomplete lines, append each content delta, and stop at data: [DONE]. Cancel abandoned readers and reject structured output if the connection ends before the completion marker.
Completion request body
{
"model": "{ready_model_id}",
"stream": true,
"max_completion_tokens": 80,
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "Describe the visible scene in one sentence." },
{ "type": "image_url", "image_url": { "url": "ovs://streams/{stream_id}?frame_index=-1" } }
]
}]
}
Renew the lease and use recent history
Call POST /streams/{stream_id}/keepalive every 90 to 120 seconds and apply the fresh publish token. An ended Stream is terminal, so replace it after a 404. To inspect motion, use video_url with start_offset_ms=-5000. Segment max_fps defaults to 1.0, and retained history lasts 600 seconds.
Measure and clean up
Overshoot-hosted models respond in 200ms. Measure first token and final [DONE], recording model, region, prompt, frame selection, output limit, and errors. On exit, cancel inference, stop keepalive and local tracks, disconnect LiveKit, and DELETE the Stream. Next, test stale frames, network loss, unavailable models, expiry, and malformed output.
Delete the Stream
curl -X DELETE https://api.overshoot.ai/v1beta/streams/$STREAM_ID \
-H "Authorization: Bearer $OVERSHOOT_API_KEY"
Frequently asked questions
Why does the browser not receive the API key?
The organization credential authorizes service requests. Keep it on a trusted server and give the browser only short-lived LiveKit room credentials.
Why can a new Stream have no image?
Creation opens the session. A LiveKit publisher still needs to connect and send frames before an ovs:// reference can resolve media.
References
Run the complete quickstart
Prove create, publish, query, keepalive, history, SSE, and deletion before expanding the application.