Tokia

POST /v1/chat/completions

Endpoint OpenAI-compatible para chamar LLMs (DeepSeek, Gemini, Claude, GPT-4o mini, Llama). Request e response seguem o schema OpenAI estavel.

Autenticacao

http
Authorization: Bearer sk-SUA_CHAVE_AQUI

Use a key gerada em /dashboard/keys. Cada key tem budget USD ligado ao saldo BRL (ver Precos). Quando saldo zera, todas as keys sao suspensas automaticamente.

Request body

CampoTipoObrigatorioDescricao
modelstringsimID do modelo (ex: gpt-4o-mini). Lista em /docs/models.
messagesarraysimArray de { role, content }. Roles: system, user, assistant, tool.
max_tokensnumbernaoLimite de tokens na resposta. Se omitido, a Tokia aplica 4.096 (ou o maximo do modelo, se menor) e devolve o header x-tokia-max-tokens-applied. Para respostas maiores, declare o valor: o custo maximo da requisicao e calculado com ele e precisa caber no seu saldo.
temperaturenumber 0-2naoAleatoriedade. 0 = deterministico, 1 = padrao, 2 = muito criativo.
top_pnumber 0-1naoNucleus sampling. Alternativa a temperature. Nao use os dois juntos.
streambooleannaoSe true, response vira SSE (Server-Sent Events) com chunks.
stopstring | arraynaoSequencia(s) que encerram a geracao. Ate 4 sequencias.
toolsarraynaoFunction calling. Suportado em modelos que aceitam (GPT-4o mini, Claude, Gemini, etc). Ver Tool Calling.
response_formatobjectnao{ "type": "json_object" } forca saida JSON valida (modelos compativeis). Ver Structured Outputs.
nnumbernaoNumero de respostas. Padrao: 1. Cada resposta extra e cobrada separadamente.

Exemplo cURL

bash
curl https://api.usetokia.com/v1/chat/completions \
  -H "Authorization: Bearer $TOKIA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [
      { "role": "system", "content": "Responda so em portugues, em 1 frase." },
      { "role": "user", "content": "Qual a capital da Franca?" }
    ],
    "temperature": 0.3,
    "max_tokens": 50
  }'

Exemplo Node.js / TypeScript

typescript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOKIA_KEY,
  baseURL: "https://api.usetokia.com/v1",
});

const completion = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [
    { role: "system", content: "Responda em portugues." },
    { role: "user", content: "O que e o PIX?" },
  ],
  max_tokens: 200,
});

console.log(completion.choices[0].message.content);

Exemplo streaming (Python)

python
from openai import OpenAI

client = OpenAI(api_key=os.environ["TOKIA_KEY"], base_url="https://api.usetokia.com/v1")

stream = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Liste 5 frutas"}],
    stream=True,
)

for chunk in stream:
    delta = chunk.choices[0].delta.content
    if delta:
        print(delta, end="", flush=True)

Formato SSE

Quando stream: true, a resposta usa Content-Type: text/event-stream. Cada evento SSE carrega um chunk JSON parcial:

text
data: {"id":"chatcmpl-...","choices":[{"delta":{"content":"Paris"}}]}

data: {"id":"chatcmpl-...","choices":[{"delta":{"content":" e"}}]}

data: {"id":"chatcmpl-...","choices":[{"finish_reason":"stop","delta":{}}],"usage":{"prompt_tokens":28,"completion_tokens":9}}

data: [DONE]

O ultimo evento e sempre data: [DONE], sinalizando fim do stream. O campo usage aparece apenas no ultimo chunk com conteudo (antes do [DONE]).

Exemplo com Tool Calling

typescript
const response = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Qual o clima em Brasilia?" }],
  tools: [
    {
      type: "function",
      function: {
        name: "get_weather",
        description: "Busca o clima atual de uma cidade",
        parameters: {
          type: "object",
          properties: {
            city: { type: "string", description: "Nome da cidade" },
          },
          required: ["city"],
        },
      },
    },
  ],
});

const toolCall = response.choices[0].message.tool_calls?.[0];
if (toolCall) {
  const args = JSON.parse(toolCall.function.arguments);
  console.log("Funcao:", toolCall.function.name, "Args:", args);
}

Entrada multimodal (imagens)

Modelos com suporte a visao (GPT-4o mini, Gemini, Claude) aceitam imagens no campo content das mensagens:

json
{
  "model": "gpt-4o-mini",
  "messages": [
    {
      "role": "user",
      "content": [
        { "type": "text", "text": "O que esta nesta imagem?" },
        {
          "type": "image_url",
          "image_url": { "url": "https://exemplo.com/foto.jpg" }
        }
      ]
    }
  ]
}

Tambem aceita base64 inline: "url": "data:image/png;base64,iVBOR...". Para mais detalhes, veja Multimodal.

Response

json
{
  "id": "chatcmpl-8x4kZ...",
  "object": "chat.completion",
  "created": 1778096405,
  "model": "gpt-4o-mini",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Paris e a capital da Franca." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 28,
    "completion_tokens": 9,
    "total_tokens": 37
  }
}

O campo finish_reason indica por que a geracao parou:

  • stop — gerou a resposta completa
  • length — atingiu max_tokens
  • tool_calls — o modelo quer chamar uma ferramenta
  • content_filter — conteudo filtrado pelo provedor

Como o custo aparece

A response do endpoint mostra usage.total_tokens e cost_billed_brl, o valor real, em reais, debitado do seu saldo (consolidado pela reconciliacao automatica em ate 60s).

Acompanhe no dashboard em /dashboard/usage, timeseries + breakdown por modelo.

Codigos de erro

Erros seguem o schema OpenAI { "error": { "type", "message", "code" } }. Tabela completa em /docs/api/errors.

HTTPcodeCausa tipica
400invalid_requestParametro invalido (model, messages, max_tokens).
402request_exceeds_balanceO custo maximo desta requisicao nao cabe no saldo. Reduza o prompt ou o max_tokens, ou adicione saldo.
422image_input_not_boundedNao conseguimos limitar o custo de imagens neste modelo. Use um modelo de visao listado ou envie so texto.
401authentication_failedKey invalida, revogada ou sem acesso ao modelo solicitado.
404model_not_foundID do modelo nao existe no catalogo Tokia.
429rate_limit_exceededThrottling, backoff e retentar.
502upstream_errorFalha temporaria. Retentar em alguns segundos.
503service_unavailableModelo temporariamente indisponivel. Retentar em alguns minutos.

Proximos passos