Base URL https://<gateway host supplied by Zalmir>/v1. Every endpoint needs Authorization: Bearer $API_KEY. Errors use one shape, listed in Errors and headers.
- Create a chat completion
POST /v1/chat/completions - Create a response
POST /v1/responses - Create a legacy completion
POST /v1/completions - Embeddings
POST /v1/embeddings - List models
GET /v1/models - Get a model
GET /v1/models/{model_id} - List a model's endpoints
GET /v1/models/{author}/{slug}/endpoints - List providers
GET /v1/providers - Get the current key
GET /v1/key - Get credits
GET /v1/credits - Get a generation
GET /v1/generation - Check a saved provider key
POST /v1/byok/check - Get or delete a saved response
GET, DELETE /v1/requests/{request_id}/response - Get the API contract
GET /openapi.json
Create a chat completion
POST /v1/chat/completions
OpenAI-compatible chat. The answer is checked against the seller's signature before you receive it, and you are charged only for a verified answer.
| Name | In | Type | Description |
|---|---|---|---|
model (required) | body | string | Model ID from /v1/models, an alias such as ~zalmir/chat, or zalmir/auto. Suffixes :nitro and :floor change the sort; :free is not available yet. |
messages (required) | body | array | The conversation. Content is text, or text and image_url parts. |
models | body | array | Several model IDs to try in order, instead of model. |
provider | body | object | Routing preferences: order, only, ignore, allow_fallbacks, sort, max_price, data_collection, zdr, require_parameters, quantizations. Or {"byok": "<provider id>"} to use your own provider key. |
stream | body | boolean | Server-sent events. Sent after the whole answer is verified, not token by token. |
stream_options.include_usage | body | boolean | Adds a final usage chunk to the stream. |
max_tokens / max_completion_tokens | body | integer | Output cap, 1 up to the route's limit. If you send both, they must match. |
n | body | integer | Only 1 is supported. |
tools, tool_choice, parallel_tool_calls | body | various | Passed to the model. Zalmir never runs tools. |
response_format | body | object | json_object or json_schema, passed to the model. |
temperature, top_p, stop, seed, penalties, logit_bias, logprobs, user, reasoning_effort | body | various | Passed to the model unchanged. |
zdr | body | boolean | Same as provider.zdr. |
Idempotency-Key | header | string | 1 to 256 printable characters, no commas. Replays a captured answer instead of running it again. Not combined with fallbacks or your own provider key. |
HTTP-Referer, X-Title | header | string | Names your app in Activity. Never sent to the seller. |
curl "$BASE_URL/chat/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "~zalmir/chat",
"messages": [{ "role": "user", "content": "Say hello." }]
}'{
"id": "chatcmpl-…",
"object": "chat.completion",
"model": "qwen/qwen3-235b-a22b-instruct-2507",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "Hello!" }, "finish_reason": "stop" }],
"usage": { "prompt_tokens": 9, "completion_tokens": 3, "total_tokens": 12 }
}Errors: 400 invalid_request, invalid_routing, invalid_model_alias, unsupported_model_variant; 402 insufficient_credits; 403 account_not_eligible; 404 model_not_found, no_eligible_provider, no_free_endpoints; 429 rate_limit_exceeded, key_limit_exceeded; 502 upstream_verification_failed, upstream_timeout; 503 capacity_unavailable, reconciliation_required.
Create a response
POST /v1/responses
The Responses API shape, run statelessly over chat. store must be false; previous_response_id, conversation and background are refused.
| Name | In | Type | Description |
|---|---|---|---|
model (required) | body | string | As for chat completions. |
input (required) | body | string or array | Text, or message items with text and image parts, and function call items. |
instructions | body | string | Becomes a system message. |
max_output_tokens | body | integer | Output cap. |
tools, tool_choice | body | various | Function tools only. Built-in tools are refused. |
text.format | body | object | text, json_object or json_schema. |
reasoning.effort | body | string | Passed to the model as reasoning_effort. |
stream | body | boolean | Named events with sequence_number, sent after verification. |
curl "$BASE_URL/responses" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "~zalmir/chat",
"input": "Say hello."
}'{
"id": "resp_…",
"object": "response",
"status": "completed",
"store": false,
"output": [ … ],
"usage": { … }
}Errors: 400 invalid_request (unsupported field, for example "Unsupported previous_response_id on this stateless chat-backed endpoint."); 402 insufficient_credits; 502 upstream_verification_failed.
Create a legacy completion
POST /v1/completions
A string prompt, sent as one user message. suffix, echo, best_of, logprobs and token-array prompts are refused.
| Name | In | Type | Description |
|---|---|---|---|
model (required) | body | string | As for chat completions. |
prompt (required) | body | string | One string. |
max_tokens | body | integer | Output cap. |
stream | body | boolean | Buffered events. |
curl "$BASE_URL/completions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "~zalmir/chat",
"prompt": "Say hello."
}'{
"id": "cmpl-…",
"object": "text_completion",
"choices": [{ "index": 0, "text": "Hello!", "finish_reason": "stop", "logprobs": null }],
"usage": { … }
}Errors: 400 invalid_request; 402 insufficient_credits.
Embeddings
POST /v1/embeddings
Not supported yet. Every call returns 400 embeddings_unsupported and nothing is charged.
curl "$BASE_URL/embeddings" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "any",
"input": "text"
}'{
"error": { "message": "No provider with embeddings support is admitted on this gateway.", "type": "invalid_request_error", "param": null, "code": "embeddings_unsupported" }
}Errors: 400 embeddings_unsupported.
List models
GET /v1/models
Models your key can use now, sorted by ID.
curl "$BASE_URL/models" \
-H "Authorization: Bearer $API_KEY"{
"object": "list",
"data": [{ "id": "…", "object": "model", "created": 0, "owned_by": "zalmir" }]
}Errors: 503 accounting_unavailable or another discovery code.
Get a model
GET /v1/models/{model_id}
One model. Encode the slash in the ID as %2F.
| Name | In | Type | Description |
|---|---|---|---|
model_id (required) | path | string | Model ID, slash encoded. |
curl "$BASE_URL/models/qwen%2Fqwen3-235b-a22b-instruct-2507" \
-H "Authorization: Bearer $API_KEY"{ "id": "qwen/qwen3-235b-a22b-instruct-2507", "object": "model", "created": 0, "owned_by": "zalmir" }Errors: 404 model_not_found.
List a model's endpoints
GET /v1/models/{author}/{slug}/endpoints
Each route Zalmir serves for one model, with its own price and limits. Metrics Zalmir has not measured are null.
| Name | In | Type | Description |
|---|---|---|---|
author (required) | path | string | First part of the model ID. |
slug (required) | path | string | The rest of the model ID. |
curl "$BASE_URL/models/qwen/qwen3-235b-a22b-instruct-2507/endpoints" \
-H "Authorization: Bearer $API_KEY"{
"data": {
"id": "qwen/qwen3-235b-a22b-instruct-2507",
"endpoints": [{ "provider_name": "…", "pricing": { … }, "context_length": …, "uptime_last_30m": null, "zalmir": { "prompt_visibility": "seller_visible" } }]
}
}Errors: 404 model_not_found.
List providers
GET /v1/providers
The dated provider reference list, with policy links and draft data-policy summaries. It is not a list of routes Zalmir serves.
curl "$BASE_URL/providers" \
-H "Authorization: Bearer $API_KEY"{ "data": [ … ] }Get the current key
GET /v1/key
This key's spending limit and usage. Decimal USD, with exact micro-dollar values under zalmir.
curl "$BASE_URL/key" \
-H "Authorization: Bearer $API_KEY"{
"data": {
"label": null, "limit": null, "limit_reset": null, "limit_remaining": null,
"usage": 0, "usage_daily": 0, "usage_weekly": 0, "usage_monthly": 0,
"zalmir": { "usage_micros": "0", "usage_scope": "v2_key_bound_net_captures", "reserved_in_limit_remaining": true }
}
}Errors: 401 invalid_api_key; 503 account_read_unavailable.
Get credits
GET /v1/credits
Total deposits and total usage for the account.
curl "$BASE_URL/credits" \
-H "Authorization: Bearer $API_KEY"{
"data": {
"total_credits": 0, "total_usage": 0,
"zalmir": { "total_credits_micros": "0", "total_usage_micros": "0", "balance_micros": "0", "reserved_micros": "0", "adjustments_micros": "0" }
}
}Errors: 401 invalid_api_key; 503 account_read_unavailable.
Get a generation
GET /v1/generation
Cost and token counts for one of your requests. Metrics Zalmir does not record are null.
| Name | In | Type | Description |
|---|---|---|---|
id (required) | query | string | gen-<request ID> or the X-Request-Id UUID. |
curl "$BASE_URL/generation?id=gen-00000000-0000-4000-8000-000000000000" \
-H "Authorization: Bearer $API_KEY"{
"data": { "id": "gen-…", "model": "…", "tokens_prompt": 9, "tokens_completion": 3, "is_byok": false, "latency": null, "zalmir": { "cost_micros": "…", "metrics_status": "not_recorded" } }
}Errors: 404 not_found; 401 invalid_api_key.
Check a saved provider key
POST /v1/byok/check
One harmless call to the provider (its model list) with your saved key. Nothing is charged or recorded, and the key is never returned.
| Name | In | Type | Description |
|---|---|---|---|
provider (required) | body | string | Provider ID, for example openai. |
curl "$BASE_URL/byok/check" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "provider": "openai" }'{ "provider": "openai", "ok": true, "code": "ok", "message": "Your saved OpenAI key works.", "provider_status": 200 }Errors: 400 byok_no_credential, byok_provider_unknown, byok_invalid_request; 403 byok_provider_disabled, account_not_eligible; 503 byok_unavailable.
Get or delete a saved response
GET, DELETE /v1/requests/{request_id}/response
If your connection dropped after a charged answer was ready, fetch the exact bytes you missed. DELETE removes the copy for good; billing is unchanged.
| Name | In | Type | Description |
|---|---|---|---|
request_id (required) | path | string | The X-Request-Id of the original request. |
curl "$BASE_URL/requests/00000000-0000-4000-8000-000000000000/response" \
-H "Authorization: Bearer $API_KEY"The original answer, byte for byte, with its original Content-Type.Errors: 404 not_found; 503 response_store_unavailable.
Get the API contract
GET /openapi.json
The exact runtime contract as OpenAPI 3.1, generated from the same route list the gateway uses.
curl "https://<gateway host supplied by Zalmir>/openapi.json" \
-H "Authorization: Bearer $API_KEY"{ "openapi": "3.1.0", "paths": { … } }