Chat Completions
POST /v1/chat/completions
The primary endpoint for generating AI responses. Compatible with OpenAI’s Chat Completions API.
PickLayer-specific parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
service_tier | string | — | Priority/flex tier. 'priority' (fast), 'auto' (standard default), 'flex' (lower-cost). See Service Tier. |
Basic Request
{
"model": "openrouter/openai/gpt-4o",
"messages": [
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Summarize the launch plan." }
],
"temperature": 0.2,
"max_tokens": 512,
"stream": false
}Response
{
"code": 200,
"message": "OK",
"type": "SUCCESS",
"data": {
"id": "chatcmpl-123",
"model": "openrouter/openai/gpt-4o",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "..." },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 143,
"completion_tokens": 201,
"total_tokens": 344,
"prompt_tokens_details": { "cached_tokens": 80, "audio_tokens": 0 }
},
"provider": "openrouter",
"request_id": "req-..."
}
}prompt_tokens_details mirrors OpenAI’s native shape and is zero-suppressed: the sub-object is omitted entirely when cached_tokens and audio_tokens are both 0 (or absent). When you route an Anthropic or Bedrock model through this endpoint, cache reads surface here as cached_tokens — the canonical cache_read_input_tokens flat field is not leaked on the chat-completions surface. See Prompt Caching for cross-endpoint cache-field semantics.
Streaming
Set "stream": true. PickLayer returns Server-Sent Events:
event: text.delta
data: {"token":"Hello"}
event: done
data: {"requestId":"...","usage":{"prompt_tokens":143,"completion_tokens":201}}Multimodal (Vision/Audio)
Image inputs
{
"model": "openai/gpt-4o",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "What do you see?" },
{ "type": "image_url", "image_url": { "url": "<picklayer-file-uuid>", "detail": "high" } }
]
}]
}Audio inputs
{
"model": "openai/gpt-4o-audio",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "Transcribe this audio" },
{ "type": "input_audio", "input_audio": { "url": "<picklayer-file-uuid>", "format": "wav" } }
]
}]
}Attaching encrypted files
Canonical-additive extension.
file_keysis a PickLayer-only top-level field. Clients sending canonical OpenAI Chat Completions requests with plaintext images are unaffected — the field has no effect unless a referenced file hasis_encrypted: true.
When a chat-completions request references a PickLayer file with is_encrypted: true (e.g., an encrypted image referenced via image_url), the gateway needs the per-file key to decrypt before forwarding plaintext to the upstream provider. The UMK never leaves the client, so the client supplies a per-file key per-request via the new top-level file_keys object.
{
"model": "openai/gpt-4o",
"messages": [{
"role": "user",
"content": [
{ "type": "text", "text": "What animal is in this image?" },
{ "type": "image_url",
"image_url": { "url": "6fefb90d-71fe-49ab-8f8f-2c5b4f2e0a01" } }
]
}],
"file_keys": {
"6fefb90d-71fe-49ab-8f8f-2c5b4f2e0a01": "Ei5dZbVaKQlnhtdtKuecl78o95fryNJPUvcQ9mSmk3c"
}
}- Key — PickLayer file UUID referenced anywhere in
messages[].content. - Value — base64url-encoded per-file key derived as
HKDF-SHA256(UMK, "picklayer:file:" + file_id). - Plaintext files do not appear here. A stray entry returns
400 unexpected_file_key.
The selection between the inline data: URL path and the signed-CDN-URL path (with opaque efk query param) is automatic. Encrypted-file references via input_audio work the same way.
See Encryption — Attaching encrypted files to chat requests for the full architectural reference, failure modes, and SDK examples.
Web Search Tool
Add {"type": "web_search"} to the tools array to enable web search:
{
"model": "openai/gpt-4o-mini",
"messages": [{"role": "user", "content": "What are today's top news headlines?"}],
"tools": [{"type": "web_search"}],
"max_tokens": 500
}Supported providers: OpenAI, Anthropic (Brave Search), Gemini (Google Search), xAI, OpenRouter.