Integração em produção
Um checklist de lançamento para uma integração que se recupera de falhas — o modelo certo, chaves e saldo protegidos, custos confirmados, acompanhamento durável das tarefas, callbacks confiáveis e os testes a rodar antes de entrar no ar.
Use esta página como checklist antes que usuários reais ou dinheiro de verdade passem a depender da sua integração. Cada seção diz o que fazer, por que isso importa e onde estão os detalhes. Se você ainda não fez a primeira chamada, comece por Prepare sua conta e pelo início rápido.
Escolha o modelo e o protocolo
- Escolha um modelo que a sua chave realmente pode chamar. Chame
GET /api/v1/modelscom a sua chave de API e use apenas modelos em queenabledeavailablesejamtrue. Leia na mesma resposta oinputSchemado modelo (a lista de campos que ele aceita) e osexamples. A página de um modelo no site diz o que ele consegue fazer; ela não prova que a sua chave pode chamá-lo agora. Veja Modelos. - Use a porta de entrada certa. Tarefas de imagem, vídeo e outras mídias usam a API de tarefas em
/api/v1(createTaske depoisrecordInfoou um callback). Modelos de texto também podem ser chamados por clientes compatíveis com OpenAI ou Anthropic em/v1, ou por clientes compatíveis com Gemini em/v1beta. Veja Texto e streaming. - Autentique-se só com chave de API. O cookie de login do console não é uma credencial de API e nunca deve ser copiado para o código.
Proteja suas chaves e seu saldo
- Mantenha a chave no seu servidor. Coloque-a numa variável de ambiente (
SPICY_API_KEY) no seu backend, nunca em código que roda no navegador, em aplicativos de celular ou num repositório público. Veja Autenticação. - Uma chave por ambiente e por serviço. Dê a cada chave o nome de quem a usa (por exemplo "production-worker"), para poder revogar uma sem parar as outras.
- Defina limites na chave de produção: um limite diário dimensionado para um dia ruim, um orçamento mensal, os modelos permitidos e, para chamadas feitas pelo servidor, uma lista de IPs permitidos. Veja restrições por chave. Ao editar uma chave, lembre que um limite em branco significa sem limite.
- Confira as datas de validade. Uma chave com data de validade para de funcionar no fim desse dia (UTC) e retorna o mesmo
401de uma chave revogada. Anote a data na sua agenda, ou não defina validade para um backend de longa duração. - Não fique sem dinheiro no meio de um lote. Uma tarefa recusada por falta de saldo retorna
40201e nunca entra na fila. Ligue o Alerta de saldo baixo em Notificações e considere a recarga automática. - Os limites da equipe também valem. Se a sua chave pertence a uma equipe, os limites diário e mensal da equipe podem barrar tarefas com
40202mesmo que os limites da própria chave não tenham sido atingidos, e toda tarefa é paga com o saldo do proprietário da equipe. Veja Limites de gasto. - Planeje a rotação da chave de assinatura dos webhooks. Rotacionar a chave no console não tem período de transição: a chave antiga para de assinar imediatamente. As entregas que ainda estão sendo repetidas passam a ser assinadas com a chave nova. Faça a rotação num período tranquilo, publique a chave nova no seu receptor na mesma hora e recupere o que tiver perdido com
recordInfo. Veja Webhooks.
Prepare a entrada no seu servidor
- Valide contra o schema atual. Siga os tipos de campo, os valores permitidos e os requisitos condicionais do
inputSchema, e valide de novo depois de trocar de modelo, porque cada modelo tem o seu. - Envie mídia do jeito suportado. Use uma URL
https://acessível publicamente ou uma entrada Base64 suportada. Para arquivos locais, peça uma URL de upload, envie os bytes comPUT, chamefiles/{fileId}/commite então passe a URIspicy://retornada no campo de entrada do modelo. Veja Mídia. - Use cada arquivo enviado dentro da validade dele. Uma URI
spicy://funciona até oexpiresAtda resposta do commit (1 dia por padrão). Não peça URLs de upload em massa que você nunca vai usar: as que ficam sem uso contam para um limite. Veja Limites de requisição.
Cote antes de aceitar uma cobrança
- Mostre o preço antes de gastar dinheiro. Envie
model,inputecallBackUrlcompletos paraPOST /api/v1/jobs/quote. MostreestimatedCost,maxCharge, a moeda (USD) eexpiresAtpara quem vai pagar. A cotação é grátis: não cria tarefa e não reserva saldo. - Envie o que foi confirmado. Uma cotação dura cinco minutos. Depois da confirmação, envie a mesma requisição para
createTask, acrescentandoquoteIdeexpectedCost. - Trate o
40901. Ele significa que a cotação expirou, que a entrada mudou ou que o preço mudou desde a cotação. Peça uma nova cotação e mostre o novo valor; nunca aceite em silêncio um valor maior. Veja Cotações. - Mantenha os valores exatos. Os valores em dinheiro são strings decimais, como
"0.008". Armazene e some esses valores com aritmética decimal, e não com ponto flutuante. Veja Cobrança.
Registre a operação de negócio
São os seus próprios registros que permitem se recuperar quando uma chamada de rede falha no meio do caminho.
- Salve antes de enviar: o ID do seu pedido ou da sua operação, uma descrição curta da requisição, sem segredos nem prompts completos (o suficiente para reconhecê-la depois), e o
Idempotency-Keyque você vai enviar. - Salve depois do aceite: o
taskIde orequest_idda resposta. - Reaproveite a chave de idempotência no mesmo envio. Envie de novo o
Idempotency-Keyoriginal para a mesma conta, a mesma chave de API e a mesma requisição dentro de 24 horas; você recebe a tarefa original de volta em vez de uma segunda cobrança. Veja Idempotência. - Trate um timeout como "desconhecido", não como "falhou". Recupere o envio original com a chave de idempotência dele antes de decidir criar um novo. Veja Solução de problemas e recuperação.
- Saiba quanto custa uma nova tentativa. Repetir uma tarefa que já falhou cria uma tarefa nova, nas condições e pelos preços atuais.
Trate callbacks e resultados de forma confiável
- Verifique todo callback. Confira a assinatura e o horário contra os bytes originais da requisição antes de interpretar o conteúdo; depois elimine duplicatas e armazene o evento. Veja Webhooks.
- Responda rápido. Responda com um
2xxna hora e faça o trabalho demorado na sua própria fila. - Conte com duplicatas e atrasos. Decida o que fazer pelo
stateda tarefa, e não pela ordem em que os callbacks chegam. - Mantenha o polling como plano B. Se um callback atrasar, leia
recordInfocom pausas cada vez maiores, e não a cada segundo. - Leia o sinal certo. HTTP
202emcreateTasksignifica que a tarefa foi aceita.state: "succeeded"significa que a geração terminou.settled: truesignifica que a cobrança é definitiva.
Limite a concorrência e guarde os resultados
- Limite as tarefas em andamento por conta e dê prazos às suas próprias requisições. Toda tarefa aceita mantém dinheiro reservado até ser liquidada.
- Respeite o
Retry-Afterem respostas429e evite muitos clientes fazendo polling em sincronia a cada segundo. Veja Limites de requisição. - Guarde os dados do catálogo em cache por pouco tempo e de forma privada, e nunca trate uma cotação como tabela de preços permanente.
- Arquive os resultados que você precisa manter. Os links de download duram 20 minutos; a mídia gerada fica guardada por no máximo cerca de 14 dias e os uploads por um dia. Você pode encurtar esses prazos ou apagar antes o conteúdo de uma tarefa com
POST /api/v1/jobs/purge. Encurtar uma configuração de retenção também pode remover resultados de tarefas que você já executou; veja Retenção. - Não conte com a desconexão para parar o trabalho. Uma tarefa aceita continua rodando e não pode ser cancelada.
Valide antes do lançamento
Comece pelas chamadas grátis: o catálogo (GET /api/v1/models), o seu saldo (GET /api/v1/chat/credit) e uma cotação. Depois rode uma geração real pequena pelo seu próprio fluxo de confirmação de custo; ela é cobrada como qualquer outra tarefa. Confira se a sua integração lida com cada um destes casos:
| Cenário | Como provocar | O que a sua integração deve fazer |
|---|---|---|
| Sucesso | Uma tarefa pequena normal | Guardar o resultado e mostrar o cost final quando settled for true |
| Entrada inválida | Enviar um valor fora do schema | Mostrar o problema; não repetir (400) |
| Combinação não suportada | Uma configuração que o modelo não consegue atender (se existir alguma) | Pedir outro valor; não repetir (40004) |
| Saldo insuficiente | Uma chave de uma conta com saldo baixo demais | Avisar o usuário para adicionar saldo; não repetir (40201) |
| Limite de gasto atingido | Uma chave com limite diário muito pequeno | Mostrar qual limite foi atingido; não repetir (40202) |
| Chave revogada ou expirada | Revogar uma chave de teste e chamar com ela | Alertar um operador; não repetir (401) |
| Timeout depois do envio | Cortar a conexão logo depois do createTask | Reenviar com o mesmo Idempotency-Key e receber a tarefa original de volta |
| O modelo recusa o conteúdo | Difícil de provocar de propósito: nos seus testes, simule uma resposta de recordInfo com state: "failed" e errorCode: "content_rejected" | Mostrar o motivo a partir de errorMessage; não repetir automaticamente |
| Callback duplicado | Reenviar um callback que você recebeu | Processá-lo uma única vez |
| Link de download expirado | Esperar mais de 20 minutos | Pedir um link novo |
Registre request_id, taskId, o horário, o state e os valores. Mantenha chaves de API e prompts completos fora dos logs gerais.
Fluxos relacionados
Cotações e compatibilidade de protocolos · Catálogo de modelos e schemas · Mídia · Webhooks · Erros · Solução de problemas e recuperação · Cobrança · Retenção
Substituição de pessoas
Um kit, dois formatos. Modelos de uma chamada trocam um rosto ou uma cabeça em uma única requisição; modelos de duas chamadas analisam o clipe antes para que você escolha quem muda.
SDK para TypeScript
Um guia passo a passo do SDK para TypeScript @spicyapi/sdk — instale, obtenha seu primeiro resultado e consulte cada método, opção e erro em linguagem simples. Os SDKs para Python, Go, PHP e Java estão documentados em páginas próprias.

