Chat Completions

POST /v1/chat/completions

POST /v1/chat/completions speaks the OpenAI chat completions wire format. Authenticate with Authorization: Bearer sapi_.... For everything not called out below — message formats, tool calling, response shape — see OpenAI Compatibility; this page only covers what’s specific to SingularityAPI.

Request notes

  • model — required. A catalog slug (e.g. deepseek-v4-flash) or contract/{slug} for a contract. Must match exactly; see Models & Pricing for the catalog.
  • Output limit fieldmax_tokens and max_completion_tokens are interchangeable; either caps output tokens on any chat model. Sending both in one request is a 400. The value must be a positive integer, no larger than the model’s max output. Omit it and the per-model default is injected server-side — check the receipt’s transformed_fields to see when the default (or a spelling rewrite) was applied.
  • stream — boolean. See Streaming for the SSE details.
  • Unsupported or reserved parameters are rejected with a 400, not silently dropped.

Function tools on gpt-5.6 models: always set reasoning_effort explicitly. On gpt-5.6-sol, gpt-5.6-terra, and gpt-5.6-luna, sending tools while omitting reasoning_effort fails with a 400 from the upstream provider (“Function tools with reasoning_effort are not supported … set reasoning_effort to ‘none’”). Include any explicit value — "none", "low", "medium", or "high" — and the same request succeeds: the platform automatically serves tools-plus-reasoning requests through the provider’s tools-compatible path. If your client treats a “none” setting by dropping the field, send the literal string "none" instead. Failed requests are never charged.

Example

curl https://api.singularityapi.dev/v1/chat/completions \
-H "Authorization: Bearer $SINGULARITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-flash",
"messages": [{"role": "user", "content": "Say hello."}]
}'

A response looks like this:

{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1690000000,
"model": "deepseek-v4-flash",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 9,
"completion_tokens": 10,
"total_tokens": 19
}
}

model in the response is the served model — the catalog model that actually ran the request. On a direct catalog call this matches what you sent; on a contract call it’s the contract’s current target.

Response headers

Every response carries:

  • x-singularity-request-id
  • x-singularity-receipt-id
  • x-singularity-contract-revision — present on contract calls only

Use the receipt ID to pull the exact cost and token usage from GET /v1/receipts/{id}.

Limits

  • A request may run up to ~230 seconds. Exceeding it returns 504 request_timeout.
  • Request bodies over the size cap are rejected with 413 request_too_large.

See Errors & Rate Limits for the full error envelope and status table.