Docs menu

POST /v1/chat/completions

The OpenAI Chat Completions wire. Base URL for OpenAI clients: https://sator-api.princep.org/v1.

Request#

bash
curl https://sator-api.princep.org/v1/chat/completions \
  -H "Authorization: Bearer $SATOR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4-flash",
    "messages": [
      {"role": "system", "content": "Be brief."},
      {"role": "user", "content": "Say hi"}
    ],
    "max_tokens": 64,
    "stream": false
  }'
FieldNotes
modelRequired. An id from Models. Unknown → 404 model_not_found.
messagesRequired. system, developer, user, assistant and tool roles.
max_tokens, max_completion_tokensOptional. Either caps output; a value above the model's max output is lowered to it.
streamtrue for server-sent events. See Streaming.
stream_options.include_usageAlways treated as true: the final streamed chunk carries usage whether or not you asked.
temperature, top_p, frequency_penalty, presence_penalty, seed, stopSampling, passed through.
tools, tool_choice, parallel_tool_callsSee Tool calling.
response_formattext, json_object or json_schema. See Tool calling.
reasoning_effortPassed through to models that take it.
prompt_cache_keyYour own conversation key, up to 256 characters. See Prompt caching.
userPassed through.

Content parts: text, and images as image_url with a base64 data URL — a remote https:// image URL is not fetched on this wire. Bodies over 5 MB are rejected 413.

Response#

json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1787593841,
  "model": "deepseek-v4-flash",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {"role": "assistant", "content": "Hi! How can I help you today?", "tool_calls": []}
    }
  ],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 9,
    "total_tokens": 21,
    "prompt_tokens_details": {"cached_tokens": 0}
  }
}

usage.prompt_tokens_details.cached_tokens is how many input tokens were served from cache and billed at the cache-read rate. Some models also return reasoning_content on the assistant message.

Every response carries an x-request-id header. Quote it to support; it is the id your debit is recorded under.

Streaming#

With "stream": true the body is text/event-stream: data: lines carrying chat.completion.chunk objects, a final chunk with usage and an empty choices array, then data: [DONE].

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"deepseek-v4-flash","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"deepseek-v4-flash","choices":[{"index":0,"delta":{"content":"Hi! How can I help"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"deepseek-v4-flash","choices":[{"index":0,"delta":{"content":" you today?"},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"deepseek-v4-flash","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":9,"total_tokens":21}}

data: [DONE]

Tool-call deltas are forwarded exactly as the model emits them. See Streaming for disconnects and billing.

Errors#

The OpenAI envelope, {"error": {"message", "type", "param", "code"}}. Every status and code is in Errors.