Chat Completions
POST /v1/chat/completions — the same request and response shape as OpenAI's API, so any OpenAI-compatible SDK or library works against Tempr Gateway without a rewrite.
Request
POST https://api.temprhq.io/v1/chat/completions
Authorization: Bearer tvk_...
Content-Type: application/json
Body parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | provider/model, e.g. openai/gpt-4o. Must be on your virtual key's allowlist. |
messages | array | Yes | Standard OpenAI message array (system/user/assistant/tool roles). |
stream | boolean | No | Default false. See Streaming. |
temperature, top_p, max_tokens | number | No | Passed through to the upstream provider as-is. |
tools, tool_choice | array / string | No | Function/tool-calling definitions, forwarded to providers that support them. See Tool calling. |
stream_options | object | No | If you set stream: true, Tempr automatically injects include_usage: true so streaming responses still carry a final usage chunk. |
Request headers
| Header | Description |
|---|---|
Authorization | Bearer tvk_... — required. See Authentication. |
x-tempr-metadata | Optional JSON object, size-capped, stored against the request log for filtering — e.g. {"customer_id":"acct_123"}. |
x-tempr-cache-ttl | Optional integer seconds (1–86400). Opts this request into response caching. |
Response (non-streaming)
The raw OpenAI-shaped completion object — Tempr does not wrap or reshape it:
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "openai/gpt-4o",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Hi there!" },
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 4,
"total_tokens": 16
}
}
Every response also carries an x-tempr-request-id header, which correlates 1:1 with the request in your request logs.
Streaming
Set "stream": true and Tempr forwards the upstream provider's chat.completion.chunk Server-Sent Events straight through — non-OpenAI providers (Anthropic, Gemini, Cohere) are translated into the same OpenAI-shaped chunks per-line, so your SSE parsing code never needs to know which provider actually served the request.
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hi"}}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":" there!"}}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":12,"completion_tokens":4,"total_tokens":16}}
data: [DONE]
Tool calling
Pass tools and (optionally) tool_choice exactly as you would to OpenAI's API. Tempr forwards them to providers that support function calling and returns tool_calls on the response message in the same shape:
{
"model": "openai/gpt-4o",
"messages": [{ "role": "user", "content": "What's the weather in Boston?" }],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}
]
}
Tempr forwards tool definitions and tool-call results — it doesn't execute tools itself. You own the loop: read the model's tool_calls, run the function on your side, and send the result back as a tool message on the next request.
Response caching
Add x-tempr-cache-ttl: <seconds> to opt a request into exact-match caching (same model, messages, and sampling params). A cache hit skips the upstream call entirely, streams back identically to a live response, and is logged and billed as a cached request rather than a full-price one. Caching requires content capture to be enabled on your account — see content capture.