curl --request POST \
--url https://api.overshoot.ai/v1beta/chat/completions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "google/gemma-4-26B-A4B-it",
"messages": [
{
"role": "user",
"content": "Reply with exactly: ok"
}
],
"max_completion_tokens": 8
}
'{
"id": "<string>",
"object": "chat.completion",
"created": 123,
"model": "<string>",
"choices": [
{
"index": 123,
"message": {
"role": "assistant",
"content": "<string>",
"tool_calls": [
{}
]
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 123,
"completion_tokens": 123,
"total_tokens": 123
},
"overshoot": {
"cache": {
"thread_id": "<string>",
"cache_hit": true,
"cached_input_tokens": 123
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": "<string>"
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"error": "validation_error",
"message": "Request validation failed",
"details": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": "<string>"
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}Chat completions
Send OpenAI-compatible chat completions and reference live Stream frames or segments with ovs:// URLs in image_url or video_url parts.
curl --request POST \
--url https://api.overshoot.ai/v1beta/chat/completions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "google/gemma-4-26B-A4B-it",
"messages": [
{
"role": "user",
"content": "Reply with exactly: ok"
}
],
"max_completion_tokens": 8
}
'{
"id": "<string>",
"object": "chat.completion",
"created": 123,
"model": "<string>",
"choices": [
{
"index": 123,
"message": {
"role": "assistant",
"content": "<string>",
"tool_calls": [
{}
]
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 123,
"completion_tokens": 123,
"total_tokens": 123
},
"overshoot": {
"cache": {
"thread_id": "<string>",
"cache_hit": true,
"cached_input_tokens": 123
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": "<string>"
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"error": "validation_error",
"message": "Request validation failed",
"details": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}{
"detail": "<string>"
}{
"detail": {
"error": {
"message": "Stream not found: <stream_id>",
"type": "stream_error",
"code": "stream_not_found",
"upstream": {
"provider": "google",
"status": 400,
"body": {},
"rate_limits": {}
}
}
}
}Referencing a stream
Themessages[].content[] array accepts standard OpenAI content parts plus two Overshoot-specific URL shapes:
image_url— points at a single frame of a stream.video_url— points at a window of frames.
ovs:// reference of the form:
ovs://streams/{stream_id}?<query>
ovs:// scheme is a reference identifier — the server parses it to pull out stream_id and the query, then resolves frames internally. It is not a fetchable URL. The <query> is what selects the moment you want. Different keys for single frames vs. windows.
Image URL — query params
Fortype: "image_url". Exactly one anchor is required.
| Param | Type | Required | Description |
|---|---|---|---|
frame_index | int | Anchor (one of) | Lifetime-indexed frame number. Negative = relative to live edge; -1 is the most recent frame. |
timestamp_ms | int | Anchor (one of) | Absolute stream-clock ms since first_frame_at_ms. |
offset_ms | int | Anchor (one of) | Offset relative to “now” (live edge at request time). Negative = past. |
tolerance_ms | int (>0) | Optional | How far the resolver may snap to find a frame. Default 100. Ignored when frame_index is set. |
direction | enum | Optional | nearest | forward | backward. Resolution preference when no exact match within tolerance. Default nearest. Ignored when frame_index is set. |
{ "type": "image_url",
"image_url": { "url": "ovs://streams/{id}?frame_index=-1" }
}
Video URL — query params
Fortype: "video_url". Requires one start anchor, accepts one optional end anchor (defaults to the live edge), plus an optional max_fps.
| Param | Type | Required | Description |
|---|---|---|---|
start_frame_index | int | Start anchor (one of) | Lifetime index where the segment begins. |
start_timestamp_ms | int | Start anchor (one of) | Absolute stream-clock ms where the segment begins. |
start_offset_ms | int | Start anchor (one of) | Offset from now where the segment begins. Negative = past (e.g. -5000 is “5s ago”). |
end_frame_index | int | End anchor (optional) | Lifetime index where the segment ends. |
end_timestamp_ms | int | End anchor (optional) | Absolute stream-clock ms where the segment ends. |
end_offset_ms | int | End anchor (optional) | Offset from now where the segment ends. |
max_fps | float (>0) | Optional | Cap on frames per second sampled from the segment. Default 1.0. Halving max_fps halves visual tokens. |
start_offset_ms=-30000&end_frame_index=523 is valid.
{ "type": "video_url",
"video_url": { "url": "ovs://streams/{id}?start_offset_ms=-5000&max_fps=2" }
}
Resolution rules
- Negative
frame_index/offset_msare evaluated againstlast_frame_index/ now at request time. The same URL can resolve to different frames on consecutive calls. - Old frames clamp. A
frame_index(orstart_frame_index) older thanfirst_available_frame_indexclamps up to the oldest available frame. Request succeeds, possibly on a different frame than asked. - Future frames fail. A
frame_indexnewer thanlast_frame_indexreturns422. There is no “wait until that frame arrives”. - Duplicate query keys (
?frame_index=1&frame_index=2) →422. - Setting more than one anchor of the same kind (e.g. two
start_*, orframe_index+timestamp_ms) →422.
Example — single-frame question
{
"model": "Qwen/Qwen3.6-27B-FP8",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "What is the person doing right now?" },
{ "type": "image_url",
"image_url": { "url": "ovs://streams/{id}?frame_index=-1" }
}
]
}]
}
Example — last-N-seconds question
{
"model": "google/gemma-4-26B-A4B-it",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "Did anything happen in the last 5 seconds?" },
{ "type": "video_url",
"video_url": { "url": "ovs://streams/{id}?start_offset_ms=-5000" }
}
]
}]
}
Authorizations
Every public HTTP request requires Authorization: Bearer <api_key>, except
GET /models and the public /billing/pricing endpoints.
401means the key is missing, unknown, or revoked.403means the key is valid but cannot access the requested resource.- The publish token returned by
POST /streamsis only for publishing media to LiveKit. It does not replace the API key for HTTP calls.
Headers
Optional hint to route the request to the region that owns the stream. If the
request reaches the wrong region the API returns 409 with a region_error body.
us-west1, us-central1 Body
OpenAI-compatible. Permissive — unknown fields are accepted for SDK compatibility.
To reference a stream's frames, include video_url or image_url content parts
whose URL uses the ovs://streams/{stream_id}?... reference scheme.
Model identifier from GET /models. Must be ready at request time.
"google/gemma-4-26B-A4B-it"
Show child attributes
Show child attributes
Optional output-token cap. OpenAI's preferred name.
Legacy alias for max_completion_tokens.
Used when supported by the selected model/provider.
When true, the response is a server-sent event stream.
Only meaningful when stream: true.
Show child attributes
Show child attributes
OpenAI-style tool definitions.
OpenAI-style tool choice.
OpenAI-style parallel tool-call setting.
Optional key for prompt-cache reuse across related requests in the same user conversation and model. See the Prompt cache guide.
Response
Completion response. JSON by default; if the request sets stream: true,
the response is an OpenAI-style SSE stream (text/event-stream) terminated by
data: [DONE].