Gateway API

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

ParameterTypeRequiredDescription
modelstringYesprovider/model, e.g. openai/gpt-4o. Must be on your virtual key's allowlist.
messagesarrayYesStandard OpenAI message array (system/user/assistant/tool roles).
streambooleanNoDefault false. See Streaming.
temperature, top_p, max_tokensnumberNoPassed through to the upstream provider as-is.
tools, tool_choicearray / stringNoFunction/tool-calling definitions, forwarded to providers that support them. See Tool calling.
stream_optionsobjectNoIf you set stream: true, Tempr automatically injects include_usage: true so streaming responses still carry a final usage chunk.

Request headers

HeaderDescription
AuthorizationBearer tvk_... — required. See Authentication.
x-tempr-metadataOptional JSON object, size-capped, stored against the request log for filtering — e.g. {"customer_id":"acct_123"}.
x-tempr-cache-ttlOptional 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"]
        }
      }
    }
  ]
}
Note

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.