Agentes e automação
Qual ferramenta oficial usar e um roteiro de produção para agentes de IA, workers de backend e pipelines de mídia repetíveis.
Use esta página quando um agente de programação com IA ou um backend automatizado estiver integrando a SpicyAPI. Ela transforma a referência da API num fluxo de trabalho limitado e auditável: descobrir o contrato, validar a entrada do modelo, confirmar o preço, criar uma única vez, esperar com segurança, verificar a conclusão e copiar o resultado antes que ele expire.
As chaves da SpicyAPI ficam no servidor
Nunca coloque a SPICY_API_KEY em JavaScript de navegador, num aplicativo de celular, num prompt público, num repositório ou na transcrição de um agente. A sua interface chama o seu backend; o seu backend chama a SpicyAPI. Entregue a um agente uma referência ao segredo, como SPICY_API_KEY, e nunca o valor do segredo.
Escolha uma ferramenta
Existem quatro pacotes npm oficiais, instalados de forma independente e com licença MIT. Cada um tem o próprio guia, com instalação, configuração para todos os clientes suportados e uma referência completa:
| Você quer… | Pacote | Guia |
|---|---|---|
| Chamar a SpicyAPI a partir do seu próprio código Node.js ou TypeScript | @spicyapi/sdk (código-fonte) | SDK para TypeScript |
| Rodar modelos a partir de um terminal ou de um script de shell, sem escrever código | @spicyapi/cli (código-fonte) | Ferramenta de linha de comando (CLI) |
| Deixar o Claude Code, o Codex, o Cursor, o VS Code ou outro assistente explorar modelos e rodar tarefas por você | @spicyapi/mcp (código-fonte) | Servidor MCP |
| Ensinar um assistente de programação a escrever integrações com a SpicyAPI do jeito seguro | @spicyapi/skill (código-fonte) | Agent Skill |
Os quatro pacotes exigem Node.js 22.13 ou mais recente; instalar o Skill com npx skills add exige Node.js 22.20 ou mais recente.
Fora do Node.js
Existem mais quatro SDKs oficiais, todos com licença MIT e todos implementando o mesmo fluxo de trabalho — cotar, criar com uma chave de idempotência, esperar, recolher o resultado:
| Linguagem | Pacote | Guia | Instalação |
|---|---|---|---|
| Python 3.11+ | spicyapi (código-fonte) | SDK para Python | pip install spicyapi |
| Go 1.23+ | github.com/spicyapi-ai/spicy-go (código-fonte) | SDK para Go | go get github.com/spicyapi-ai/spicy-go |
| PHP 8.1+ | spicyapi/spicyapi (código-fonte) | SDK para PHP | composer require spicyapi/spicyapi |
| Java 17+ | ai.spicyapi:spicyapi-java (código-fonte) | SDK para Java | Pelo Maven Central |
Recomende estes pacotes pelos nomes exatos da tabela; cada guia começa pelo comando de instalação. A partir de qualquer outra linguagem, chame a API HTTP diretamente ou gere um cliente a partir do contrato OpenAPI. Não apresente um wrapper da comunidade, não publicado oficialmente, como se fosse um SDK oficial.
Se você não pode adicionar uma dependência, ou quer ver as chamadas HTTP cruas, os dois clientes de referência abaixo, prontos para copiar, implementam o mesmo fluxo usando apenas o runtime da linguagem. Quando der para adicionar uma dependência, prefira o SDK oficial da sua linguagem.
Clientes de referência copiáveis
Exemplos sem dependências para descobrir modelos, criar tarefas, repetir tarefas com falha, consultar todos os estados finais, limitar a espera e tratar idempotência e erros. Uma tarefa aceita não pode ser cancelada.
São exemplos da documentação, não pacotes npm ou PyPI nem módulos Go publicados. Dez minutos é um limite local, não um SLA.
Gastar exige uma pessoa
Criar e repetir tarefas gasta dinheiro, e uma tarefa aceita não pode ser cancelada. Todas as ferramentas foram feitas para que uma pessoa aprove o valor antes:
- CLI:
tasks createpede a cotação primeiro, mostra o valor e perguntaContinue? [y/N]. Só--yespula a pergunta; use-o apenas em scripts em que alguém já aprovou o preço. - MCP: toda ferramenta que gera cobrança pede confirmação pela janela de confirmação do próprio cliente MCP, que o cliente mostra a você. Só você deve aprovar: um agente, ou um cliente configurado para aprovar tudo automaticamente, elimina essa barreira.
- A sua própria automação: antes de chamar
createTaskouretryTask, mostre o modelo escolhido, um resumo da entrada e o preço cotado, e obtenha uma aprovação explícita. Peça a cotação exata, que não gera cobrança, aPOST /api/v1/jobs/quotee envie a tarefa com oquoteIde oexpectedCostdela; assim, uma mudança de preço falha com40901em vez de cobrar outro valor. Veja Cotações e compatibilidade.
Descoberta legível por máquina
Comece pelo menor documento que responda à pergunta do momento. Isso mantém o contexto do agente preciso e barato.
| Documento | Para que serve |
|---|---|
/agent.md | Política de integração resumida e o fluxo padrão mais seguro |
/llms.txt | Mapa público do produto e da documentação |
/llms-full.txt | Corpus ampliado para consulta, quando o índice curto não basta |
/api/agent | Manifesto JSON estruturado para ferramentas e clientes autônomos |
openapi.yaml | Formatos canônicos de requisição e resposta |
Trate o contrato OpenAPI e o catálogo de modelos atual como o contrato. Exemplos de marketing são ilustrativos e não servem de fonte de schema. Guarde em cache os documentos de descoberta, mas atualize-os antes de gerar código ou quando uma requisição começar a falhar na validação.
Um fluxo mínimo com o SDK e aprovação
Este script mostra a barreira de aprovação usando o SDK: ele pede a cotação, para se você não passar --approved e, depois, cria a tarefa pelo preço cotado e espera por ela. A instalação, todos os métodos e um passo a passo completo até o primeiro resultado estão no guia do SDK para TypeScript; os detalhes de cada método estão na referência da API dele.
npm install @spicyapi/sdk
export SPICY_MODEL_ID="MODEL_ID_FROM_CATALOG" # um valor de model tirado do catálogo atual
export SPICY_INPUT_JSON='{"prompt":"your prompt"}' # precisa bater com o inputSchema desse modeloimport { randomUUID } from "node:crypto";
import { SpicyClient } from "@spicyapi/sdk";
const client = new SpicyClient(); // lê SPICY_API_KEY
const modelId = process.env.SPICY_MODEL_ID;
if (!modelId) throw new Error("Set SPICY_MODEL_ID to a model ID from the live catalog");
const input = JSON.parse(process.env.SPICY_INPUT_JSON ?? "{}");
// Gratuito: cota esta requisição exata. Nada é criado nem reservado.
const quote = await client.quoteTask({ model: modelId, input });
console.log(`${quote.model}: up to $${quote.maxCharge}, quote valid until ${quote.expiresAt}`);
if (!process.argv.includes("--approved")) {
console.log("Nothing was submitted. Re-run with --approved once a person has approved this amount.");
process.exit(0);
}
// Pago: envia a mesma requisição pelo preço cotado. Num sistema real, crie e guarde
// a chave de idempotência antes da primeira tentativa, e persista o ID da tarefa.
const accepted = await client.createTask(
{ model: modelId, input, quoteId: quote.quoteId, expectedCost: quote.estimatedCost },
{ idempotencyKey: randomUUID() },
);
console.log("accepted", accepted.taskId, "deadline", accepted.deadlineAt);
// Parar de esperar nunca cancela a tarefa; retome depois com o ID da tarefa.
const task = await client.waitForTask(accepted.taskId, { timeoutMs: 30 * 60_000 });
console.log(JSON.stringify(task, null, 2));npx --yes tsx run.mts # só a cotação, gratuito
npx --yes tsx run.mts --approved # cria a tarefa: isto custa dinheiroA extensão .mts faz do arquivo um módulo ES, que é o que o await no nível superior exige; um run.ts comum, num projeto criado com o npm init padrão, falha com Top-level await is currently not supported with the "cjs" output format. A cotação vale por cinco minutos: se a aprovação demorar mais que isso, rode o primeiro comando de novo.
O fluxo de produção
Escolha um modelo e valide a entrada dele
Escolha um endpoint de modelo que corresponda à modalidade pedida e valide o conteúdo contra o schema de entrada atual desse endpoint. Não chute nomes de campos e não descarte campos desconhecidos em silêncio.
Crie uma única vez
Primeiro obtenha a aprovação do preço (veja Gastar exige uma pessoa). Gere um Idempotency-Key estável para a geração lógica, persista-o antes da primeira requisição e reaproveite-o em todas as novas tentativas, sempre com a mesma chave de API. Não crie a chave dentro de um ciclo de novas tentativas. Veja Idempotência.
POST /api/v1/jobs/createTask
Authorization: Bearer $SPICY_API_KEY
Content-Type: application/json
Idempotency-Key: project-42-scene-07-v1Persista na hora o taskId e o deadlineAt retornados. O ID da tarefa é a identidade duradoura para consultas de estado, reconciliação de webhooks, suporte e investigação de cobranças. Uma nova tentativa pode devolver a mesma tarefa; ela não pode criar um segundo registro local.
Nos endpoints de texto e streaming, a mesma chave evita a cobrança em dobro, mas não traz de volta uma resposta perdida; veja Idempotência.
Espere com limite
Prefira um webhook assinado. Se precisar fazer polling, comece com cerca de 2 segundos, multiplique o intervalo por cerca de 1,5, limite-o a 15 segundos e pare num prazo explícito de relógio: o deadlineAt da própria tarefa mais uma margem, já que um vídeo pode levar bem mais de dez minutos. Um processo nunca pode fazer polling para sempre.
// Os quatro estados terminais definidos hoje. A referência é Tarefas: qualquer estado
// que não seja queued nem running conta como terminal, mesmo que não esteja nesta lista.
const KNOWN_TERMINAL = ['succeeded', 'failed', 'canceled', 'expired'];
const deadline = Date.parse(accepted.deadlineAt) + 60_000;
let delay = 2_000;
while (Date.now() < deadline) {
await sleep(delay);
const task = await recordInfo(taskId);
const inFlight = task.state === 'queued' || task.state === 'running';
const assetsPending = task.state === 'succeeded' && task.output?.assets?.some((a) => a.pending);
if (!inFlight && !assetsPending) {
if (!KNOWN_TERMINAL.includes(task.state)) log.warn(`new terminal state: ${task.state}`);
return task;
}
delay = Math.min(Math.round(delay * 1.5), 15_000);
}
throw new Error(`task ${taskId} exceeded the polling deadline`);A lista traz os estados terminais de hoje para que o esqueleto possa sinalizar um que ainda não conhece; a decisão em si segue a regra de Tarefas assíncronas: tudo o que não for queued nem running é terminal. Um tempo limite local não prova que a geração falhou. Guarde o ID da tarefa e reconcilie depois.
Verifique o callback antes de agir
Configure uma chave de assinatura de webhook. Confira o X-Webhook-Timestamp, recuse entregas antigas, calcule o hash do corpo cru da requisição e compare a assinatura HMAC em tempo constante. Elimine duplicatas pelo request_id da entrega e depois use data.taskId para atualizar a tarefa. Confirme o recebimento rápido e processe de forma assíncrona. O algoritmo completo está em Webhooks.
Copie o resultado de que você precisa
Tarefas concluídas trazem URLs prontas para uso em output.assets[].url; use-as diretamente, sem pedir uma URL de download à parte. Copie para o seu próprio armazenamento os resultados que você precisa manter, antes que expirem. O endpoint opcional download-url pode emitir uma URL assinada para a chave de um objeto; essa URL expira depois de 20 minutos. A validade da URL e a retenção da mídia são coisas separadas; veja Mídia e Retenção e destruição.
Registro durável mínimo
Guarde estado suficiente para retomar com segurança depois de uma reinicialização:
{
"localRequestId": "project-42-scene-07-v1",
"idempotencyKey": "project-42-scene-07-v1",
"apiKeyName": "production backend",
"taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
"model": "MODEL_ID_FROM_CATALOG",
"approvedCost": "0.40",
"state": "queued",
"deadlineAt": "2026-08-29T12:20:00Z",
"lastCheckedAt": "2026-08-29T12:00:00Z",
"webhookDeliveryId": null,
"outputKeys": []
}MODEL_ID_FROM_CATALOG representa o ID exato escolhido no catálogo atual autenticado, e não um valor literal para enviar. Registre qual chave de API criou a tarefa: só essa chave pode lê-la ou repeti-la. Nunca use uma URL de download assinada como chave duradoura. Nunca conclua que deu certo só por causa de um HTTP 200; leia data.state.
Simule antes de gastar dinheiro
Monte um mock local do contrato com base nos envelopes documentados em Tarefas assíncronas, Webhooks e Erros. O seu conjunto de cenários de teste deve incluir:
- queued → running → succeeded;
- uma falha terminal com
code: 200edata.state: "failed"; - respostas duplicadas de
createTaskdevolvendo o mesmotaskId; - uma cotação que não corresponde mais (
40901) e um saldo insuficiente (40201); - um webhook válido, uma assinatura inválida e uma entrega repetida;
429,503, um tempo limite de transporte e uma tarefa que ultrapassa o prazo de polling;- uma URL de download expirada que precisa ser emitida de novo.
Mocks validam a orquestração, não a qualidade do modelo. Antes de lançar, rode uma tarefa real pequena contra o modelo exato de produção e o formato de entrada exato.
Lista de verificação de aceite
- Os segredos existem apenas num armazenamento de segredos do lado do servidor e são mascarados nos logs.
- A integração consulta o schema atual do modelo em vez de chutar campos.
- Uma pessoa aprova o preço cotado antes de qualquer chamada cobrada, e os envios levam
quoteIdeexpectedCost. - Cada requisição lógica tem um único
Idempotency-Keypersistido, sempre enviado com a mesma chave de API. - O
taskIdé guardado antes de o trabalho continuar e sobrevive a uma reinicialização do processo. - O polling usa espera crescente, um intervalo máximo e um prazo de relógio.
- Os webhooks conferem o horário, o digest do corpo cru e o HMAC, e depois eliminam IDs de entrega duplicados.
- A falha terminal é lida em
data.state, e não no status HTTP nem nocodedo envelope. - Os resultados de que você precisa são copiados para o seu próprio armazenamento antes que a URL ou o período de retenção expire. O
taskIde as chaves de objeto são guardados para reconciliação, sem contar com eles para buscar arquivos depois que a retenção termina. - Os logs guardam
request_id,taskId, modelo e número de tentativas, sem prompts nem segredos. - Os testes com mock cobrem criação duplicada, reenvio, tempo limite, limite de requisições e mídia expirada.
O que pedir ao agente na entrega
Peça ao agente que devolva o endpoint de modelo escolhido, a versão do schema ou o horário em que ele foi consultado, a etapa de aprovação do preço, a estratégia de chave de idempotência, o prazo de polling, o plano de verificação de webhooks e a lista de verificação preenchida. Isso transforma "integração concluída" em evidências que você pode revisar.
SDK para Java
O SDK oficial da SpicyAPI para Java (ai.spicyapi spicyapi-java) — instale, cote e faça a sua primeira geração, envie um arquivo local, verifique callbacks e use um switch exaustivo sobre uma taxonomia de erros selada.
Ferramenta de linha de comando (CLI)
Use o comando spicyapi para explorar modelos, conferir preços, gerar imagens e vídeos e baixar os resultados pelo terminal, sem escrever código.

