curl https://gateway.gatelit.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: GatelitKey glk_your_service_key" \
-d '{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "What is the capital of France?"}]
}'{
"id": "<string>",
"object": "chat.completion",
"created": 123,
"model": "<string>",
"choices": [
{
"index": 123,
"message": {
"role": "user",
"content": "Explain quantum entanglement in one sentence."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 123,
"completion_tokens": 123,
"total_tokens": 123
}
}{
"error": true,
"code": "gateway_error",
"message": "Missing or invalid 'model' field. Expected format: 'provider/model-name'"
}{
"error": true,
"code": "unauthorized",
"message": "Invalid or expired token"
}{
"error": true,
"code": "provider_error",
"message": "Upstream error 503 — Service Unavailable"
}Chat Completions
OpenAI-compatible chat endpoint. Any provider, any model.
curl https://gateway.gatelit.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: GatelitKey glk_your_service_key" \
-d '{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "What is the capital of France?"}]
}'{
"id": "<string>",
"object": "chat.completion",
"created": 123,
"model": "<string>",
"choices": [
{
"index": 123,
"message": {
"role": "user",
"content": "Explain quantum entanglement in one sentence."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 123,
"completion_tokens": 123,
"total_tokens": 123
}
}{
"error": true,
"code": "gateway_error",
"message": "Missing or invalid 'model' field. Expected format: 'provider/model-name'"
}{
"error": true,
"code": "unauthorized",
"message": "Invalid or expired token"
}{
"error": true,
"code": "provider_error",
"message": "Upstream error 503 — Service Unavailable"
}POST /v1/chat/completions
Send a chat request to any supported provider through the gateway. The response format is identical to OpenAI’s chat completions API regardless of which provider handles the request.
Auth
All three schemes are accepted:Authorization: GatelitKey glk_...
Authorization: GatelitSigned <signed-token>
Bearer (OIDC) is supported but in Alpha. Contact us if you need OIDC auth.Request
| Field | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Provider/model in provider/model-id format |
messages | array | Yes | Array of {role, content} objects |
max_tokens | integer | No | Max output tokens |
temperature | number | No | 0–2, stripped for reasoning models |
stream | boolean | No | Enable SSE streaming |
user | string | No | End-user ID — forwarded to the provider and used as the logged end-user ID when no token claim or x-gatelit-end-user-id header is present |
metadata | object | No | Arbitrary string/number/boolean tags — stripped before forwarding, stored on the log entry, filterable in the dashboard |
Gateway-specific fields
| Field | Description |
|---|---|
output_schema | Structured output config (json_object or json_schema mode) |
prompt_id | Tag request with a saved prompt’s slug for log correlation |
fallback_chain | Ordered fallback models with trigger conditions |
Metadata
metadata lets you attach business context to a request — environment, feature, session, tenant, experiment — without polluting the provider call:
{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "Hello!"}],
"metadata": {
"environment": "production",
"feature": "doc-summariser",
"session_id": "sess_123"
}
}
- Values must be
string,number, orboolean— nested objects and arrays are rejected (400) - Keys are limited to 64 characters and values to 128 characters; at most 100 keys per request
- The field is stripped before forwarding to the provider — it never reaches the upstream API
- It appears on the log entry and can be filtered with
key=valuein the dashboard
user in the body — a standard OpenAI field. It is forwarded to OpenAI-compatible providers unchanged, and used as the logged end-user ID when no signed-token claim or x-gatelit-end-user-id header set one. (Non-OpenAI providers that lack the field — e.g. Anthropic, Google — ignore it; the gateway still logs it.)
Response
Non-streaming
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "openai/gpt-4o",
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "..." },
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 15,
"completion_tokens": 8,
"total_tokens": 23
}
}
Response headers
| Header | Description |
|---|---|
x-gatelit-request-id | Unique request ID for log lookup |
x-gatelit-model | Resolved model in provider/model format |
x-gatelit-auth-mode | Bearer, GatelitSigned, or GatelitKey |
x-gatelit-fallback | "true" when a fallback model was used |
x-gatelit-fallback-reason | rate_limit, provider_error, timeout, refusal_detected |
x-gatelit-fallback-model | The fallback model that responded |
Streaming
Whenstream: true, the response is an OpenAI-compatible SSE stream. Each data: line is a JSON chunk. Final line is data: [DONE].
Examples
curl https://gateway.gatelit.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: GatelitKey glk_..." \
-d '{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "Hello!"}]
}'
import { GatelitClient } from "@gatelit/sdk"
const client = new GatelitClient({
gatewayUrl: "https://gateway.gatelit.dev",
getToken: async () => ({ token: "glk_...", scheme: "GatelitKey" }),
})
const response = await client.chat({
model: "openai/gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
})
Structured output
curl https://gateway.gatelit.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: GatelitKey glk_..." \
-d '{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "Alice is 30."}],
"output_schema": {
"mode": "json_schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"}
},
"required": ["name", "age"]
}
}'
With fallback chain
curl https://gateway.gatelit.dev/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: GatelitKey glk_..." \
-d '{
"model": "openai/gpt-4o",
"messages": [{"role": "user", "content": "Explain TCP"}],
"fallback_chain": [
{"model": "anthropic/claude-3-5-haiku-20241022", "triggers": ["rate_limit"]},
{"model": "google/gemini-2.5-flash"}
]
}'
import { GatelitClient } from "@gatelit/sdk"
const client = new GatelitClient({
gatewayUrl: "https://gateway.gatelit.dev",
getToken: async () => ({ token: "glk_...", scheme: "GatelitKey" }),
})
const response = await client.chat({
model: "openai/gpt-4o",
messages: [{ role: "user", content: "Explain TCP" }],
fallbackChain: [
{ model: "anthropic/claude-3-5-haiku-20241022", triggers: ["rate_limit"] },
{ model: "google/gemini-2.5-flash" },
],
})
// When a fallback fired, the response exposes it:
if (response.meta.usedFallback) {
console.log(`Handled by ${response.meta.fallbackModel} (${response.meta.fallbackReason})`)
}
triggers): rate_limit, provider_error, timeout, refusal_detected. Without triggers, the fallback fires on any failure. A fallback candidate never falls through when its provider is disabled for your org — it is skipped in order.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | gateway_error | Invalid model format or missing fields |
| 401 | unauthorized | Missing, invalid, or expired token |
| 502 | provider_error | Upstream provider returned an error |
Authorizations
OIDC JWT issued by your auth provider (Alpha). Full self-serve configuration is coming soon — contact us for early access. Use this for browser/frontend clients where a user is signed in.
Body
Model in provider/model-id format.
Supported providers: openai, anthropic, google, mistral.
"openai/gpt-4o"
"anthropic/claude-3-5-sonnet-20241022"
"google/gemini-2.5-flash"
"mistral/mistral-large-latest"
1Show child attributes
Show child attributes
Maximum tokens to generate. The gateway maps this to the correct
upstream parameter — max_completion_tokens for OpenAI reasoning
models, max_tokens for everything else.
1024
Sampling temperature. Omit for reasoning models (o3, o3-mini, o4-mini) — the gateway strips it automatically based on the model catalog.
0 <= x <= 20.7
Nucleus sampling. Supported by all providers.
0 <= x <= 1When true, the response is an OpenAI-compatible SSE stream.
Each data: line is a JSON object regardless of the upstream provider.
End-user identifier (standard OpenAI field). Forwarded to the provider
unchanged, and used as the logged end-user ID when no signed-token
claim or x-gatelit-end-user-id header is present.
"customer_42"
Arbitrary tags attached to the request — environment, feature, session, tenant, and so on. Values must be string, number, or boolean; keys are limited to 64 characters and string values to 128 characters. Stripped before forwarding to the provider, stored on the log entry, and filterable in the dashboard.
Show child attributes
Show child attributes
{
"environment": "production",
"feature": "doc-summariser",
"session_id": "sess_123"
}
Structured output configuration. The gateway translates to the correct provider-specific format automatically.
Show child attributes
Show child attributes
Associates this request with a saved prompt in the dashboard. The prompt's content is not used — only the ID is logged for correlation.
Ordered list of fallback models to try if the primary model fails. Each entry specifies a model and the error types that trigger it.
Show child attributes
Show child attributes
Response
Successful response.
- Non-streaming:
Content-Type: application/json - Streaming:
Content-Type: text/event-stream
Response headers always include:
x-gatelit-request-id— use for log lookup in the dashboardx-gatelit-model— the provider/model that respondedx-gatelit-auth-mode—Bearer,GatelitSigned, orGatelitKey