Cotações e compatibilidade de protocolos
Descubra o preço exato de uma requisição antes de pagar, envie-a por esse preço, recupere-se de uma resposta perdida e entenda como são cobradas as APIs compatíveis de texto e vídeo.
Cotar uma requisição exata
Uma cotação informa o preço de uma requisição exata antes de você pagar. Ela é gratuita, não cria tarefa nenhuma e não reserva dinheiro. Depois, você envia a mesma requisição com a cotação anexada, e ela só é aceita pelo preço que foi mostrado a você.
Os comandos abaixo são para um terminal de macOS ou Linux, com SPICY_API_KEY definida como no Início rápido. MODEL_ID_FROM_CATALOG é um marcador: use um valor de model do seu catálogo atual (GET /api/v1/models) e tire cada campo de input do schema desse modelo.
Salve a requisição que você pretende enviar
Crie um arquivo chamado request.json com exatamente o model, o input e, se for usar, o callBackUrl que você vai enviar:
{
"model": "MODEL_ID_FROM_CATALOG",
"input": { "prompt": "A cinematic night portrait" }
}Peça o preço
curl https://api.spicyapi.ai/api/v1/jobs/quote \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @request.json{
"code": 200,
"msg": "success",
"data": {
"quoteId": "QUOTE_ID_FROM_RESPONSE",
"model": "MODEL_ID_FROM_CATALOG",
"estimatedCost": "0.008",
"maxCharge": "0.008",
"currency": "USD",
"quantity": "1",
"unit": "per_image",
"expiresAt": "2026-09-17T10:05:00Z"
},
"request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}Os valores vêm como texto decimal, em dólares americanos. maxCharge é o máximo que esta requisição pode custar; hoje ele é sempre igual a estimatedCost. quantity e unit mostram o que está sendo contado, por exemplo segundos de vídeo. Mostre o valor e o expiresAt a quem for aprovar o gasto.
A cotação faz as mesmas verificações de um envio de verdade, então ela já pode falhar: 400 (a entrada não bate com o schema do modelo), 40201 (saldo insuficiente), 40202 (um limite de gasto da chave ou a cota da plataforma) ou 403 (esta chave não tem permissão para usar o modelo).
Envie a mesma requisição com a cotação anexada
Em até cinco minutos, envie a requisição, sem alterar nada, para createTask, com mais dois campos: quoteId, tirado da cotação, e expectedCost, com o estimatedCost cotado. Esta etapa custa dinheiro.
{
"model": "MODEL_ID_FROM_CATALOG",
"input": { "prompt": "A cinematic night portrait" },
"quoteId": "QUOTE_ID_FROM_RESPONSE",
"expectedCost": "0.008"
}SPICY_IDEMPOTENCY_KEY="$(uuidgen)" # uma vez por tarefa nova; reaproveite só para reenviar esta mesma requisição
curl https://api.spicyapi.ai/api/v1/jobs/createTask \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
--data-binary @submit.jsonA resposta é a resposta normal de tarefa, 202 Accepted, descrita no Início rápido. A cotação não substitui o Idempotency-Key: envie os dois.
| A cotação fica vinculada a | Ela deixa de valer quando |
|---|---|
| A sua conta e a chave de API que a pediu | Você envia com outra chave |
O model, o input e o callBackUrl exatos | Qualquer um deles muda, nem que seja um caractere do prompt. A ordem dos campos e os espaços não importam |
| O preço naquele momento | Passam cinco minutos, ou o preço muda |
40901 quer dizer que a cotação não descreve mais a requisição
Entradas alteradas, outra chave de API, cotação expirada, preço alterado ou um expectedCost diferente do cotado aparecem todos do mesmo jeito: a aceitação falha com 40901, e nada é cobrado. Peça a cotação e confirme de novo. Não tire quoteId e expectedCost para forçar a requisição a passar sem preço confirmado.
POST /api/v1/jobs/stream, o stream de texto nativo, aceita cotação do mesmo jeito; veja Texto e streaming.
Recuperar-se de uma resposta perdida
Se um envio estourou o tempo limite ou a conexão caiu, você não sabe se ele foi aceito. Para createTask, retry e POST /v1/videos:
- Reenvie a requisição original com o
Idempotency-Keyoriginal, usando a mesma chave de API. Você recebe de volta a tarefa original, no estado em que ela estiver agora, e não é cobrado duas vezes. - Não crie outra tarefa com uma chave nova. Chave nova significa geração nova e cobrança nova.
- Repetir uma requisição já aceita continua valendo depois que a cotação expira. A expiração barra a aceitação, não a tarefa que a aceitação já criou.
- Um
409não quer dizer "não foi criada". Ou a requisição mudou (é um trabalho novo, que precisa de chave nova), ou ela foi enviada com outra chave de API da mesma conta (reenvie com a chave original). Veja Idempotência. - Leia
costesettledemrecordInfopara saber a cobrança final.
Requisições de texto e streaming não podem ser recuperadas assim
A resposta a uma requisição de texto (/api/v1/jobs/stream e os endpoints de texto em /v1 e /v1beta) é enviada a você à medida que é gerada e não fica armazenada. Reenviar uma chave já aceita devolve um erro em vez da resposta: 400 com o mesmo corpo, 409 com um corpo diferente. Nada mais é cobrado, mas a resposta perdida não pode ser buscada. Para ter uma resposta de novo, envie a requisição com uma chave nova e pague por ela. Veja Quais endpoints leem o cabeçalho.
Estimativa não é liquidação
estimatedCost é o que esperamos cobrar. Um marcador de fim de texto num stream só diz que os bytes pararam de chegar. Nenhum dos dois prova que a cobrança é definitiva. Para tarefas, quem prova é settled: true junto com cost em recordInfo. Chamadas de texto não retornam ID de tarefa: encontre a cobrança delas listando as tarefas com a mesma chave de API (GET /api/v1/jobs) ou em Console → Registros, e considere cost definitivo quando settled for true.
Cotações nas ferramentas oficiais
A CLI e o servidor MCP pedem a cotação e perguntam a uma pessoa antes de toda chamada cobrada, então você não precisa construir essa etapa por conta própria:
- CLI:
spicyapi tasks quoteinforma o preço de uma requisição;spicyapi tasks createpede a cotação de novo, mostra o valor e pergunta antes de criar. Veja Custos, confirmação e segurança. - MCP: o assistente pode pedir cotações à vontade, mas criar uma tarefa faz o seu cliente de IA perguntar a você, com o preço. Veja Custos, confirmação e segurança.
- SDK:
quoteTaskretorna a cotação; passe oquoteIde oestimatedCostdela paracreateTaskourun.
Um agente não pode confirmar no lugar do usuário
A confirmação existe para que uma pessoa decida. Um agente que responde a ela sozinho, ou um cliente configurado para aprovar tudo automaticamente, eliminou a única barreira de gasto desse caminho.
Compatibilidade de texto e vídeo
A SpicyAPI também fala os formatos da OpenAI, da Anthropic e do Google Gemini para modelos de texto, e o formato OpenAI Videos para vídeo. A lista completa de endpoints está na referência da API; requisições, streams e erros de cada protocolo estão em Texto e streaming.
URL base. O formato da OpenAI usa https://api.spicyapi.ai/v1. Os SDKs da Anthropic e do Google GenAI acrescentam /v1 ou /v1beta sozinhos, então, para eles, defina a URL base como https://api.spicyapi.ai.
Credencial. Uma só chave de API para todos, no cabeçalho Authorization: Bearer. O cabeçalho x-api-key, usado pelo SDK da Anthropic, e o x-goog-api-key, usado pelo SDK do Google GenAI, também são aceitos. Um ?key= na URL nunca é.
Modelo. Escolha um modelo exato do catálogo atual. Se ferramentas, mensagens com imagem e opções de geração funcionam depende do schema desse modelo, não do protocolo que você escolheu.
Formato da resposta. Cada protocolo retorna o próprio envelope, e não o envelope {code, msg, data, request_id} da plataforma.
Campos de raciocínio
Modelos de chat que expõem o texto do raciocínio podem retornar uma string opcional em message.reasoning_content, ou em delta.reasoning_content durante o streaming. Ao continuar depois de uma chamada de ferramenta, você pode preservá-la na mensagem de assistente correspondente, quando o schema atual do modelo permitir.
usage.completion_tokens_details.reasoning_tokens descreve a parte de raciocínio já incluída em completion_tokens; não a some de novo. Nem todo modelo retorna texto de raciocínio ou esse detalhamento de tokens.
Dois formatos que vale conhecer antes de construir
- Responses exige a conversa inteira em
input.previous_response_idnão é suportado. - Videos aceita JSON com
model,prompt,input_reference,secondsesize, que são convertidos para os campos próprios do modelo. Oidde vídeo retornado também é um ID de tarefa aceito porrecordInfo. O endpoint de conteúdo dele redireciona com HTTP302para uma URL assinada de curta duração.
As APIs compatíveis cobram o preço vigente na aceitação
quoteId e expectedCost valem só para jobs/createTask e jobs/stream. /v1 e /v1beta usam o preço vigente quando a requisição é aceita e recusam esses dois campos, então não há confirmação de preço por chamada nesse caminho. Quando um fluxo de trabalho precisar confirmar um limite de cobrança, use a API nativa de tarefas; para limitar tudo o que uma chave pode gastar, defina os limites diário, mensal e acumulado dela, como explicado em Autenticação.
Para um exemplo de chat com streaming usando os clientes oficiais da OpenAI, da Anthropic e do Google, veja Use um SDK oficial. A CLI e o servidor MCP enviam e acompanham tarefas nativas; eles não transmitem tokens de chat.

