Skip to main content

Endpoint

Compatible with the OpenAI chat completions format. Supports streaming, multimodal input (images, video, audio, and documents), tool calling, structured output, and prompt caching.

Request Parameters

Message Format

Each message has a role and content:

Vision (multimodal)

Use a content array to include images or video:
Video input:
Image and video URLs must be publicly accessible.

Audio understanding

Send audio to a model that supports audio input with an audio_url content part:
You may also inline the audio as a base64 data URL:
The URL must be publicly accessible (and unexpired, if presigned). Audio must be 20 MB or smaller; larger files return a 400. Place the audio part before the text part for the best results.
Supported formats vary by provider. OpenAI audio models (e.g. gpt-audio) accept only wav and mp3; an unsupported format returns a 400. Gemini models (e.g. gemini-3-1-pro-preview) additionally accept m4a, aac, ogg, and flac.

Files and documents (PDFs)

Attach a document to a message with a file content part. Pass the file inline as a base64 data URL in file.file_data:
You may also reference a document by URL, useful for files generated in a workspace:
Pass exactly one of file_data (a base64 data URL) or file_url. The URL must be publicly accessible (and unexpired, if presigned). A document must be 24 MB or smaller; larger files return a 400. Place the document before the text part for the best results.
Supported file types: application/pdf. Requesting an unsupported file type returns a 400 error. Referencing files by OpenAI file_id is not supported. Inline the file with file_data or pass file_url.
A 400 response for an unsupported type looks like:

Prompt caching

When several requests start with the same prompt prefix, Oxen can serve that prefix from its prompt cache instead of processing it again. Cache hits make long prompts faster. You don’t need extra parameters: send the same OpenAI-format request and caching happens upstream. To get cache hits:
  • Put stable content first. The system prompt, tool definitions, and any large documents or few-shot examples belong at the start of the request. Content that changes per request, such as the user’s question, goes last.
  • Keep the prefix byte-identical. Any change to the prefix, even a timestamp in the system prompt or reordered tools, invalidates the cache from that point on.
  • Use a plain string system message for Claude. The cache breakpoint is added to the first system message when its content is a string.
  • Send requests close together. Cache entries expire after a few minutes of inactivity, depending on the provider.

Reading cache usage

When the provider reports cache activity, usage includes prompt_tokens_details.cached_tokens: the number of prompt tokens served from the cache. Cached tokens are already counted in prompt_tokens, so don’t add them on top. Streaming responses report the same field in the final usage chunk.
cost is the amount charged for the request, in currency. If a response has no prompt_tokens_details, the provider didn’t report any cache activity for that request.

Example

Send two requests that share a long system prompt and compare cache usage:
Python
Output:
The first request writes the prefix to the cache. The second reads it back.

Examples

Basic text generation

Response

usage may also include prompt_tokens_details.cached_tokens. See Prompt caching.

Analyze a PDF

Understand audio

To send a local file, base64-encode it into a data: URL:
Python

Streaming

Returns server-sent events. Each chunk has a delta instead of a full message:

Tool calling

When the model uses a tool, finish_reason is "tool_calls":

Structured output (JSON mode)

Errors