Docs · API compatível com OpenAI
Chat completions
O dialeto Chat Completions da OpenAI. Não guarda estado: você envia a conversa inteira a cada chamada, e nada é guardado como conversa. As chamadas continuam sendo medidas, então contam para a sua cota.
POST/v1/chat/completions#
- Auth: a sua chave de API, em
Authorization: BearerouX-API-Key. - Limite: 20 requisições por minuto por conta por padrão, um contador que todos os endpoints
/v1dividem com os outros endpoints que têm um número por minuto próprio. Veja limites e cotas. - Corpo: JSON, com
Content-Type: application/json.
Requisição#
| Campo | Tipo | Obrigatório | Notas |
|---|---|---|---|
model | string | sim | um id de modelo de modelos, com no máximo 320 caracteres |
messages | array | sim | de 1 a 200 mensagens, veja abaixo |
stream | boolean | não | true para server-sent events. O padrão é false |
stream_options.include_usage | boolean | não | acrescenta um chunk final com a contagem de tokens a uma resposta em stream |
tools | array | não | ferramentas de função, veja chamadas de ferramenta |
tool_choice | string ou objeto | não | auto, none, required, ou {"type":"function","function":{"name":"…"}} |
reasoning_effort | string | não | low, medium, high, xhigh ou max, nos modelos que suportam. Qualquer outro valor é descartado |
collections | array de inteiros | não | ids de suas coleções, de 1 a 5. Os trechos delas que dizem respeito à última mensagem do usuário são acrescentados à mensagem de sistema. Não faz parte da API da OpenAI: um SDK envia como campo extra do corpo |
| parâmetros de amostragem e outros campos da OpenAI | não | aplicados ou ignorados conforme o modelo, veja abaixo |
Uma requisição malformada devolve 422 no formato de erro da OpenAI, com code: null.
Mensagens#
Cada mensagem tem um role e um content:
roleésystem,user,assistantoutool.contenté uma string, ounullnuma mensagem do assistente que traztool_calls. No máximo 200000 caracteres por mensagem.- Um array de partes de conteúdo, a forma usada para enviar imagens, é recusado com
422(The messages.0.content field must be a string.). Imagens não são suportadas neste endpoint. - Uma mensagem do assistente pode trazer
tool_calls, e uma mensagemtooltraz otool_call_idque ela responde.
Quais parâmetros valem#
O que acontece com os parâmetros de amostragem depende do driver do modelo, um campo de GET /api/v1/profiles. Um modelo cujo driver é ollama é servido pelos servidores Ollama do próprio operador. Todos os outros drivers, que cobrem os provedores de nuvem e também qualquer servidor compatível com OpenAI que o operador rode, caem na segunda coluna.
| Parâmetro | driver é ollama | qualquer outro driver |
|---|---|---|
temperature, top_p, max_tokens, max_completion_tokens, stop, seed, frequency_penalty, presence_penalty | repassados ao servidor do modelo | ignorados |
response_format, n, parallel_tool_calls, user, logit_bias, logprobs, top_logprobs | repassados como estão. O servidor do modelo decide se têm algum efeito | ignorados |
tools, tool_choice | repassados | aplicados |
reasoning_effort | não se aplica | aplicado quando o modelo tem ajuste de esforço |
stream_options.include_usage | sempre ligado nos streams | aplicado |
Um parâmetro ignorado não é um erro: a requisição tem sucesso e o parâmetro não tem efeito. Se o tamanho da saída ou a aleatoriedade importam para você, confira primeiro o driver do modelo.
Resposta#
{
"id": "chatcmpl-0b0f3c0e-6c4e-4d6f-9a0e-2f3b1d7a9c11",
"object": "chat.completion",
"created": 1767225600,
"model": "claude-sonnet-4-6@anthropic",
"choices": [
{ "index": 0, "message": { "role": "assistant", "content": "Hello! Nice to meet you." }, "finish_reason": "stop" }
],
"usage": { "prompt_tokens": 14, "completion_tokens": 8, "total_tokens": 22 }
}modelé o id que o gateway resolveu para a requisição. Ele mostra uma substituição quando você enviou um nome sem servidor que o gateway não conhecia, mas não mostra um fallback para o seu modelo padrão. Veja modelos.- Há uma escolha nos modelos de nuvem: não envie
n. Para modelos que não sãoollama,finish_reasonéstopoutool_calls. Para modelosollamaé o que o servidor do modelo informar, o que incluilength. - O texto de raciocínio que alguns modelos produzem nunca é devolvido.
Headers#
| Header | Significado |
|---|---|
X-Request-Id | identifica a requisição HTTP. Envie o seu, com até 64 letras, dígitos, - e _, e ele é reaproveitado |
X-Inference-Request-Id | identifica a chamada ao modelo. Passe-o ao suporte |
X-Inference-Model, X-Inference-Server | o alvo resolvido, a título de informação |
X-Inference-Collections, X-Inference-Excerpts | só quando a chamada nomeou collections: os ids que foram usados e quantos trechos entraram no prompt. Veja coleções |
X-RateLimit-Limit, X-RateLimit-Remaining | o seu limite de requisições e quanto resta dele |
Streaming#
Com "stream": true a resposta é text/event-stream. Cada evento é uma linha data: {…} seguida de uma linha em branco, e o stream termina com data: [DONE].
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":1767225600,"model":"claude-sonnet-4-6@anthropic","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":1767225600,"model":"claude-sonnet-4-6@anthropic","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":1767225600,"model":"claude-sonnet-4-6@anthropic","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","created":1767225600,"model":"claude-sonnet-4-6@anthropic","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":8,"total_tokens":22}}
data: [DONE]O chunk de uso, o de choices vazio, aparece só quando você define stream_options.include_usage, exceto nos modelos ollama, em que ele está sempre presente. Nos modelos ollama os chunks são os do próprio servidor do modelo, então o chunk inicial só com o papel, do exemplo, não é garantido. Leia o stream como eventos, não como linhas de JSON: o gateway não envia comentários nem linhas de keep-alive.
Chamadas de ferramenta#
Declare funções com tools. Quando o modelo quer chamar uma, a resposta traz tool_calls e finish_reason é tool_calls.
curl -s "$SHVIA_URL/v1/chat/completions" \
-H "Authorization: Bearer $SHVIA_API_KEY" -H "Content-Type: application/json" \
-d '{
"model": "'"$SHVIA_MODEL"'",
"messages": [{ "role": "user", "content": "What is the weather in Lisbon?" }],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}]
}'{
"id": "chatcmpl-…",
"object": "chat.completion",
"created": 1767225600,
"model": "claude-sonnet-4-6@anthropic",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Lisbon\"}" } }
]
},
"finish_reason": "tool_calls"
}
],
"usage": { "prompt_tokens": 61, "completion_tokens": 18, "total_tokens": 79 }
}Execute a função você mesmo e depois envie a conversa de volta com a chamada e o resultado dela:
{
"model": "claude-sonnet-4-6@anthropic",
"messages": [
{ "role": "user", "content": "What is the weather in Lisbon?" },
{ "role": "assistant", "content": null, "tool_calls": [
{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Lisbon\"}" } }
] },
{ "role": "tool", "tool_call_id": "call_1", "content": "18 degrees, clear" }
],
"tools": [ … the same tools … ]
}Num stream, cada chamada de ferramenta chega inteira numa única entrada delta.tool_calls, e não em fragmentos incrementais dos argumentos.
Erros#
Os erros usam o formato da OpenAI: {"error": {"message", "type", "param", "code"}}. Decida pelo status HTTP e por code; o texto de message pode estar em outro idioma e pode mudar.
| Status | code | Quando |
|---|---|---|
| 401 | invalid_api_key | a chave está ausente, errada, expirada ou revogada |
| 403 | permission_denied | o seu grupo não pode usar este modelo, uma cota acabou, ou o grupo não pode usar servidores remotos. Não repita às cegas |
| 404 | model_not_found | o id traz um servidor e o gateway não tem esse modelo lá, ou o modelo não é exposto |
| 422 | null | o corpo falhou na validação |
| 422, 404, 403 | invalid_collections, collection_not_found, collections_blocked_by_lgpd | o campo collections não pôde ser usado. Veja coleções |
| 429 | nenhum | limite de requisições atingido. O corpo é {"message": "Too Many Attempts."} quando você envia Accept: application/json; leia Retry-After |
| 502 | empty_response | o modelo não devolveu nada. Não vale para modelos ollama |
| 502, 503, ou o status do próprio provedor | service_unavailable | o servidor do modelo, ou todos os servidores da cadeia, não puderam ser alcançados ou recusaram a chamada. Se todos os modelos da cadeia falham, a recusa de um provedor de nuvem mantém o status do provedor, por exemplo 401 quando a sua chave do provedor é rejeitada. Se outro modelo pode responder, ele responde, e você recebe o 200 dele (veja modelos) |
| 504 | read_timeout | o modelo parou de responder no meio da resposta. O corpo acrescenta um objeto partial com a resposta que chegou, e o header X-Inference-Incomplete: read_timeout é enviado. Não vale para modelos ollama |
Para modelos ollama, uma resposta vazia é um 200 comum com content vazio, e um modelo que trava termina, depois de uma longa espera, como um 502 com service_unavailable. Uma recusa das credenciais do próprio gateway pelo servidor do modelo é informada como 502, nunca como 401, para que você não regenere uma chave de API que está boa.
Não suportado#
- Imagens e outras partes de conteúdo nas mensagens.
- O
/v1/completionslegado e o/v1/embeddingsda OpenAI. Os embeddings estão em/api/v1/embeddings. - Mais de uma escolha (
n). - Recuperar um modelo ou uma completion passada pelo id.
Tratamento de dados#
- Nada é guardado como conversa. Cada chamada é registrada para medição, com o texto da sua última mensagem mascarado e encurtado. Veja seus dados.
- Quando o modelo não está na infraestrutura do próprio operador, identificadores comuns no texto das mensagens, como endereços de e-mail, números de CPF e CNPJ e telefones, são trocados por marcadores como
[EMAIL]e[CPF]antes de ele sair. O mascaramento é por padrões: não reconhece nomes nem dados livres, e não mexe nos argumentos das chamadas de ferramenta. Não use um modelo assim para processar esses identificadores.