DOCS / API REFERENCE / CHAT COMPLETIONS

Chat Completions

http
Authorization: Bearer lattice_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Requires an application API key. Subject to that application's model allowlist, monthly quota, and rate limit.

Request body

The body is validated as a strict object — any field not listed below causes 400 invalid_request, it is never silently dropped.

modelstring, required
A registry model id or alias (see Model Registry & Routing). Unknown model → 404 model_not_found.
messagesChatMessage[], required
1 to 200 items. Each message is itself a strict object: { role: 'system' | 'user' | 'assistant', content: string }, content up to 32,000 characters.
streamboolean, default false
When true, the response is text/event-stream instead of a single JSON body. See Streaming.
temperaturenumber, optional
0 to 2.
max_tokensinteger, optional
>= 1. Also used as the upper bound for quota reservation before dispatch.
top_pnumber, optional
stopstring | string[], optional
json
type ProviderAdapter = {
  id: ProviderId;
  createChatCompletion(
    request: ChatCompletionRequest,
    ctx: ProviderRequestContext,
  ): Promise<ChatCompletionResponse>;
  streamChatCompletion(
    request: ChatCompletionRequest,
    ctx: ProviderRequestContext,
  ): AsyncGenerator<ChatCompletionChunk, void, void>;
};

type ProviderRequestContext = {
  apiKey?: string;
  providerModel: string;
  signal: AbortSignal;
};
NOTE
Not supported today: tools/tool_calls, n (multiple completions), logprobs, response_format, image/multimodal content. Sending any of these fails validation rather than being ignored, so a client finds out immediately rather than silently getting different behavior than expected.

Non-streaming response

200 OK, content-type: application/json:

json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1755878400,
  "model": "gpt-4o",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "..." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 42,
    "completion_tokens": 118,
    "total_tokens": 160
  }
}

finish_reason is one of 'stop' | 'length' | 'content_filter', normalized the same way across every provider — see Providers for how each upstream's native stop reason maps into these three.

Streaming

Set "stream": true. The response is text/event-stream; each event's data: payload is a JSON-encoded chunk, and the stream ends with a literal data: [DONE]:

text
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1755878400,"model":"gpt-4o","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1755878400,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"Sure"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1755878400,"model":"gpt-4o","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":42,"completion_tokens":118,"total_tokens":160}}

data: [DONE]

Chunk shape:

ts
type ChatCompletionChunk = {
  id: string;
  object: 'chat.completion.chunk';
  created: number;
  model: string;
  choices: [
    {
      index: number;
      delta: { role?: 'assistant'; content?: string };
      finish_reason: 'stop' | 'length' | 'content_filter' | null;
    },
  ];
  usage?: { prompt_tokens: number; completion_tokens: number; total_tokens: number } | null;
};

usage is only present on the terminal chunk, and only when the upstream provider reports it there.

WARNING
Failover for a streaming request only happens before the first chunk is sent. If a provider fails mid-stream after content has already reached the client, the connection just ends — see Request Lifecycle for why partial output is never silently replaced.

Errors

See the full table in Errors. The two most common on this endpoint beyond auth failures:

Statuserror.codeCause
403model_not_permittedThe application has an allowedModels list and this model isn't on it.
429quota_exceededThe application's monthly token quota is exhausted.
429rate_limit_exceededThe application's per-minute request limit is exceeded.
404model_not_foundmodel doesn't match any registry id or alias.
502all_providers_failed / provider_errorEvery candidate provider failed.
LATTICE — INTERNAL AI INFRASTRUCTURE
GITHUB © 2026