Skip to main content
POST
/
chat
/
completions
Chat completions
curl --request POST \
  --url https://api.overshoot.ai/v1/chat/completions \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "model": "google/gemma-4-E4B-it",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "What does it say on my shirt?"
        },
        {
          "type": "video_url",
          "video_url": {
            "url": "ovs://streams/cc3e3f79-c5c4-4d1c-985e-028b42030569?start_offset_ms=-5000"
          }
        },
        {
          "type": "image_url",
          "image_url": {
            "url": "ovs://streams/cc3e3f79-c5c4-4d1c-985e-028b42030569?frame_index=-1"
          }
        }
      ]
    }
  ]
}
'
{
  "id": "<string>",
  "object": "chat.completion",
  "created": 123,
  "model": "<string>",
  "choices": [
    {
      "index": 123,
      "message": {
        "role": "<string>",
        "content": "<string>"
      },
      "finish_reason": "<string>"
    }
  ],
  "usage": {
    "prompt_tokens": 0,
    "completion_tokens": 0,
    "total_tokens": 0
  }
}

Documentation Index

Fetch the complete documentation index at: https://docs.overshoot.ai/llms.txt

Use this file to discover all available pages before exploring further.

Referencing a stream

The messages[].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.
Both wrap an ovs:// reference of the form:
ovs://streams/{stream_id}?<query>
The 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

For type: "image_url". Exactly one anchor is required.
ParamTypeRequiredDescription
frame_indexintAnchor (one of)Lifetime-indexed frame number. Negative = relative to live edge; -1 is the most recent frame.
timestamp_msintAnchor (one of)Absolute stream-clock ms since first_frame_at_ms.
offset_msintAnchor (one of)Offset relative to “now” (live edge at request time). Negative = past.
tolerance_msint (>0)OptionalHow far the resolver may snap to find a frame. Default 100. Ignored when frame_index is set.
directionenumOptionalnearest | 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

For type: "video_url". Requires one start anchor, accepts one optional end anchor (defaults to the live edge), plus an optional max_fps.
ParamTypeRequiredDescription
start_frame_indexintStart anchor (one of)Lifetime index where the segment begins.
start_timestamp_msintStart anchor (one of)Absolute stream-clock ms where the segment begins.
start_offset_msintStart anchor (one of)Offset from now where the segment begins. Negative = past (e.g. -5000 is “5s ago”).
end_frame_indexintEnd anchor (optional)Lifetime index where the segment ends.
end_timestamp_msintEnd anchor (optional)Absolute stream-clock ms where the segment ends.
end_offset_msintEnd anchor (optional)Offset from now where the segment ends.
max_fpsfloat (>0)OptionalCap on frames per second sampled from the segment. Default 1.0. Halving max_fps halves visual tokens.
Start and end anchor types may differ — 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_ms are evaluated against last_frame_index / now at request time. The same URL can resolve to different frames on consecutive calls.
  • Old frames clamp. A frame_index (or start_frame_index) older than first_available_frame_index clamps up to the oldest available frame. Request succeeds, possibly on a different frame than asked.
  • Future frames fail. A frame_index newer than last_frame_index returns 422. 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_*, or frame_index + timestamp_ms) → 422.

Example — single-frame question

{
  "model": "Qwen/Qwen3.5-9B",
  "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-E4B-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" }
      }
    ]
  }]
}
For more usage patterns, see the Chat Completion guide.

Authorizations

Authorization
string
header
required

All requests must include Authorization: Bearer <api_key>. Get a key from the Overshoot dashboard. Listing models (GET /models) does not require auth.

Body

application/json

OpenAI-compatible. Permissive — unknown fields are accepted and ignored. 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
string
required

Model identifier from GET /models. The model must be ready at request time.

Example:

"Qwen/Qwen3.5-9B"

messages
object[]
required

Conversation turns. content may be a plain string or a list of typed parts (text, image_url, video_url). Use image_url / video_url parts to reference a stream's frames or windows — see the URL grammar below.

response_format
object

OpenAI-shape response_format. Passed through to the upstream model unchanged.

max_completion_tokens
integer | null

Cap on tokens generated. OpenAI's preferred name.

max_tokens
integer | null

Legacy alias for max_completion_tokens. Both work; pick one.

Response

Completion response.

id
string
required

Unique completion ID. Different on every retry.

object
string
default:chat.completion
required

Always chat.completion.

created
integer
required

Unix seconds when the completion was generated.

model
string
required

Echoed model ID from the request.

choices
object[]
required

Generated completions. Length = 1 unless the request set n > 1.

usage
object