Catálogo de modelos e schemas
Use o catálogo autenticado em tempo real para selecionar modelos disponíveis, consultar preços e montar solicitações com o JSON Schema atual.
createTask.model recebe exatamente o model retornado pela resposta autenticada de GET /api/v1/models. Seu input é definido pelo inputSchema atual do mesmo item. Essa resposta em tempo de execução é a única fonte confiável para um ID que pode ser chamado.
Não copie um ID de uma página estática
Registros de lançamento, páginas de famílias e catálogos dos criadores dos modelos servem para descoberta. Eles podem incluir entradas planejadas, desativadas ou renomeadas e nunca devem substituir o catálogo em tempo real quando ele estiver vazio. Antes de executar operações pagas, consulte o catálogo autenticado e exija tanto enabled: true quanto available: true.
Nos exemplos desta página, MODEL_ID_FROM_CATALOG é um marcador, não um modelo real: substitua-o por um valor de model do seu catálogo em tempo real. A consulta ao catálogo é gratuita.
Selecionar um modelo e uma entrada validada
Os schemas das solicitações variam entre modelos. Por isso, a forma segura de obter um exemplo executável é selecionar juntos um modelo disponível e um de seus exemplos validados pelo servidor:
const response = await fetch(
'https://api.spicyapi.ai/api/v1/models?includeSchema=1&includeExamples=1',
{ headers: { Authorization: `Bearer ${process.env.SPICY_API_KEY}` } },
);
const envelope = await response.json();
if (!response.ok || envelope.code !== 200) throw new Error(envelope.msg);
const selected = envelope.data.items.find(
(item) => item.enabled && item.available && item.examples?.length,
);
if (!selected) throw new Error('No callable model with a validated example');
const createTaskBody = {
model: selected.model,
input: selected.examples[0].input,
};Cada exemplo contém um input completo que o servidor já validou com o schema atual e pode ser enviado sem alterações.
Consultar o catálogo por código
GET /api/v1/models
GET /api/v1/models/{model}curl "https://api.spicyapi.ai/api/v1/models?modality=video" \
-H "Authorization: Bearer $SPICY_API_KEY"A lista não é paginada: uma resposta contém todos os modelos visíveis para sua chave que correspondem aos filtros. Todos os parâmetros são opcionais.
| Parâmetro | Significado |
|---|---|
modality | image, video, audio ou text |
provider | Criador do modelo, com correspondência exata e diferenciação entre maiúsculas e minúsculas, por exemplo ByteDance. Copie o valor de provider de um item |
task | Uma tarefa, como text-to-image, edit (edição de imagem), image-to-video, text-to-video, reference-to-video, speech-to-text, video-analyze, video-edit, video-extend, character-animation ou chat. Consulte tasks no catálogo para obter o conjunto atual. A edição de imagem aceita duas grafias: os modelos são publicados como .../edit, mas tasks os classifica como image-to-image, e o filtro aceita ambas |
search | Texto presente em qualquer parte do ID ou nome de exibição do modelo, sem diferenciar maiúsculas e minúsculas, com até 128 caracteres |
includeSchema | true ou 1 inclui o inputSchema de cada item |
includeExamples | true ou 1 inclui os examples de cada item, validados com o schema atual |
O endpoint de um único modelo, GET /api/v1/models/{model}, sempre inclui inputSchema e examples; includeSchema e includeExamples só afetam a lista. As barras do ID podem permanecer como estão; aplique codificação percentual somente se seu cliente HTTP tratar um parâmetro de caminho como um único segmento. Um modelo inexistente ou que não é oferecido no momento retorna 404.
Uma resposta de lista abreviada:
{
"code": 200,
"msg": "success",
"data": {
"total": 1,
"items": [
{
"model": "MODEL_ID_FROM_CATALOG",
"family": "…",
"displayName": "…",
"provider": "…",
"modality": "video",
"tasks": ["image-to-video"],
"async": true,
"enabled": true,
"available": true,
"availability": "available",
"taskTimeoutSeconds": 1200,
"maxOutputDurationSeconds": 10,
"quantityField": "duration_seconds",
"pricing": [
{ "variant": "generate_audio=false;resolution=720p", "unit": "per_second", "price": "0.05", "currency": "USD" },
{ "variant": "generate_audio=true;resolution=720p", "unit": "per_second", "price": "0.08", "currency": "USD" }
],
"startingPrice": { "variant": "generate_audio=false;resolution=720p", "unit": "per_second", "price": "0.05", "currency": "USD" },
"badges": ["audio_output"],
"relatedModels": [],
"version": "v1",
"updatedAt": "2026-09-16T16:47:57Z"
}
]
},
"request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}Os preços acima são ilustrativos. inputSchema e examples só aparecem nos itens da lista quando solicitados.
Campos que os clientes devem usar
| Campo | Finalidade |
|---|---|
model | Valor exato a enviar como createTask.model, no formato publisher/model/task |
family | Identificador estável da família do produto para agrupar endpoints relacionados |
displayName | Nome legível deste endpoint |
provider | Criador do modelo, como o laboratório que o desenvolveu |
modality / tasks | Tipo de mídia em que o endpoint é agrupado no catálogo e tarefa que ele executa. modality orienta a navegação e o filtro modality; não garante o tipo do arquivo de saída: um endpoint speech-to-text fica em audio e responde com texto. Veja Formato da saída |
toolkit | Família de ferramentas à qual o endpoint pertence; atualmente, apenas subject-swap. O campo fica ausente quando o modelo não pertence a um conjunto de ferramentas, portanto verifique o valor, não apenas a existência da chave. Assim como badges, é uma classificação e nunca afeta aceitação, preço ou validação. Veja Troca de sujeito |
async | true: crie uma tarefa e colete o resultado por consultas de status ou webhook. false: a resposta volta diretamente na chamada |
inputSchema | JSON Schema 2020-12 usado para gerar formulários e validar solicitações |
examples | Entradas validadas com o schema atual; na lista, só são retornadas quando solicitadas |
enabled | Indica se a entrada pode ser chamada agora. O catálogo também lista entradas publicadas, mas ainda não abertas, e entradas pausadas pela plataforma; elas retornam false. Verifique junto com available antes de enviar uma tarefa |
available | Indica se o modelo pode ser chamado agora. false significa que uma chamada falharia, por exemplo por não haver preço atual |
availability | Fase informada: planned, available, preview (campos e saídas ainda podem mudar) ou maintenance (falhas temporárias, com retorno previsto) |
pricing / startingPrice | Seus preços; veja Como interpretar preços |
quantityField | Campo de entrada cujo valor representa a quantidade cobrada; em vídeo, geralmente duration_seconds. Vazio significa que cada chamada conta como uma unidade. Sempre leia o valor do catálogo |
taskTimeoutSeconds | Prazo de execução da plataforma para uma tarefa. Não é a duração da mídia |
maxOutputDurationSeconds | Maior duração que o modelo pode produzir, obtida de maximum na propriedade duration_seconds; omitido quando não há máximo declarado |
badges | Marcadores de capacidades e licença, como commercial_use ou no_watermark. Ignore valores que você não reconhece |
relatedModels | Alternativas ou próximos passos selecionados, como IDs de modelos que você pode chamar |
version / updatedAt | Acompanhamento de mudanças: compare os valores para saber se uma consulta posterior trouxe alterações |
mature e policyTier são rótulos informativos. Não participam da decisão de aceitar uma solicitação.
Como interpretar preços
Cada entrada de pricing representa uma faixa de preço:
| Campo | Significado |
|---|---|
unit | per_image, per_second (de mídia gerada), per_request ou per_1k_tokens |
price | Seu preço por unidade em dólares americanos, como string decimal. Já reflete as tarifas da sua conta, que podem variar entre contas |
variant | Configurações que selecionam a faixa. Vazio quando o modelo tem preço único; somente o valor, como 720p, quando um campo seleciona a faixa; pares field=value unidos por ; e ordenados pelo nome do campo, como generate_audio=false;resolution=480p, quando vários campos a selecionam |
currency | Sempre USD |
regularPrice, offerLabel, offerPercent, offerEndsAt | Presentes somente enquanto uma oferta ao cliente está vigente: preço anterior, nome da oferta, porcentagem e término |
startingPrice é a entrada mais barata, não o preço das suas configurações. Os campos que selecionam uma faixa são listados em inputSchema["x-pricing"].variantFields, quando presente; caso contrário, são os campos marcados com x-ui.affects_price: true, exceto quantityField. Um campo omitido usa seu default do schema.
- Modelos de mídia: seu custo é
price × quantity, em que a quantidade é o valor dequantityFieldna entrada, ou uma unidade quandoquantityFieldestá vazio. Alguns endpoints acrescentam uma cobrança separada por entrada adicional, geralmente por imagem de referência. Considere-a parte real da cobrança, não um detalhe de arredondamento: em um endpoint de edição que aceita uma lista de imagens de referência, preencher a lista pode multiplicar o valor, enquantounit,quantity,variante opriceda faixa permanecem exatamente iguais aos de uma imagem única. Assim, a fórmula acima informa um valor menor que o real sem nenhum sinal visível. A indicação legível por máquina é um campo marcado comx-ui.affects_price: trueque não é oquantityFieldnem aparece emx-pricing.variantFields: ele altera o valor sem selecionar uma faixa. Nesses endpoints, tratepricingcomo valor mínimo e obtenha o total por um orçamento. - Modelos de texto (
per_1k_tokens): um número só não descreve a cobrança.priceé apenas a tarifa de tokens de saída por 1.000 tokens. Tokens de entrada e de entrada em cache têm tarifas próprias, geralmente menores, e são cobrados conforme o uso medido de cada chamada. Não multipliquepricepelo total de tokens. Os preços por milhão de tokens de entrada, entrada em cache e saída aparecem na página de cada modelo e emprice.perMillionTokensno catálogo público.
Para saber o valor de uma solicitação exata na API nativa antes de pagar, use POST /api/v1/jobs/quote. A cobrança final aparece no registro da tarefa, em cost com settled: true, e em Faturamento.
Cache do catálogo
- A resposta do catálogo pode ser mantida em cache por até 60 segundos (
Cache-Control: private, max-age=60). Use somente um cache privado por conta: os preços são específicos da conta, portanto nunca os coloque em um cache de CDN público ou compartilhado. - Além disso, não consulte o catálogo antes de cada tarefa. Leituras do catálogo usam a capacidade de leitura da conta, independentemente do envio de tarefas. Consultar o catálogo antes de cada chamada ainda desperdiça a capacidade de leitura; Veja Limites de solicitações.
- Atualize-o periodicamente, por exemplo a cada poucos minutos, após um erro de validação
400e quando o envio de uma tarefa para aquele modelo for recusado. - Guarde a
versione oupdatedAtdo registro usado para identificar mudanças em uma consulta posterior. - Nunca distribua um schema fixo no código nem use uma página estática como alternativa quando o catálogo em tempo real não tiver nenhum item disponível para chamadas.
Regras compartilhadas de Schema e Playground
inputSchema usa JSON Schema 2020-12. As palavras-chave padrão controlam a validação no servidor; o objeto x-ui de cada propriedade apenas descreve a ordem, a apresentação e as indicações de atualização de orçamento do Playground. Os clientes devem ignorar extensões de apresentação desconhecidas, que nunca substituem required, enumerações, limites ou condições. Veja o contrato Spicy Schema completo.
Criar sua própria tabela de parâmetros por modelo
Este site não inclui tabelas estáticas de parâmetros por modelo. Isso não é falta de cuidado: modelos e campos mudam toda semana, qualquer cópia fixa fica desatualizada, e usar um parâmetro antigo custa um erro 400 ou um preço incorreto. Os parâmetros têm uma única fonte: o inputSchema retornado pelo catálogo. O Playground renderiza esse mesmo documento, e o SDK o usa para validar.
Como transformar cada parte do schema em uma tabela
| No schema | Na sua tabela de parâmetros |
|---|---|
Uma chave de properties | Nome do parâmetro. Os campos são padronizados entre modelos: um significado, um nome em todos eles |
Presença em required | Obrigatório ou opcional |
anyOf / allOf | Obrigatório sob condição. anyOf = forneça pelo menos um destes; em allOf, if → then = se fornecer A, você precisa fornecer B |
type | Tipo |
description | Texto de ajuda. Está em inglês e pode ser exibido como está; você não precisa escrever o seu |
enum | Valores aceitos. Quando houver x-ui.enum_labels, use-o para transformar os valores em rótulos legíveis |
minimum / maximum | Intervalo aceito; x-ui.step define o passo e x-ui.unit, o sufixo (s, px) |
minItems / maxItems | Em uma lista, quantidade de entradas aceitas. Uma linha que omite isso não informa ao leitor o limite que ele encontrará |
items | Em uma lista, formato de cada entrada. Quando items.type é object, esse subschema é um schema de objeto completo: leia seu required, seu additionalProperties e o type, a description, o intervalo e o default de cada subcampo; apresente-os em uma tabela aninhada, não em um campo de texto livre |
default | Valor padrão aplicado quando o campo é omitido |
x-ui.order | Critério de ordenação, em ordem decrescente. Não ordene pela sequência de chaves de properties: a ordem das chaves de objetos JSON não faz parte do contrato |
x-ui.primary | Fixar no topo como entrada principal |
x-ui.advanced | Pode ser recolhido em uma seção avançada |
x-ui.affects_price | Marcar que afeta o preço; uma mudança de valor exige um novo orçamento |
x-ui.widget | Controle a renderizar em um formulário editável; treze valores, veja Spicy Schema |
As condições só aparecem na raiz de inputSchema, em dois formatos: anyOf, em que cada condição lista somente campos required (“forneça pelo menos um destes”), e allOf, em que cada condição é if → then (“se fornecer A, você precisa fornecer B”). Não as deduza pela família nem espere oneOf, not ou dependentSchemas. Novos endpoints seguem os campos canônicos do Spicy Schema; os antigos seguem seu schema em tempo real.
Consultar o schema
const modelId = 'MODEL_ID_FROM_CATALOG'; // the exact `model` value from GET /api/v1/models
const res = await fetch(`https://api.spicyapi.ai/api/v1/models/${modelId}`, {
headers: { Authorization: `Bearer ${process.env.SPICY_API_KEY}` },
});
const { data } = await res.json();
const schema = data.inputSchema;
const rows = Object.entries(schema.properties)
.sort(([, a], [, b]) => (b['x-ui']?.order ?? 0) - (a['x-ui']?.order ?? 0))
.map(([name, prop]) => ({
name,
required: (schema.required ?? []).includes(name),
type: prop.type,
description: prop.description,
values: prop.enum
? prop.enum.map((v) => prop['x-ui']?.enum_labels?.[v] ?? v)
: prop.minimum !== undefined || prop.maximum !== undefined
? [`${prop.minimum ?? ''}–${prop.maximum ?? ''}${prop['x-ui']?.unit ?? ''}`]
: [],
default: prop.default,
affectsPrice: prop['x-ui']?.affects_price === true,
advanced: prop['x-ui']?.advanced === true,
}));Esse exemplo se limita intencionalmente a valores escalares: deixa values vazio para uma lista, pois uma lista define o que aceita em items, minItems e maxItems, não em enum ou em um intervalo. Amplie-o antes de publicar: uma linha que mostra apenas array, sem formato das entradas nem limite de tamanho, é uma linha que não permite ao leitor agir.
O registro de um modelo também retorna examples: cada exemplo é uma entrada completa já validada no servidor com o schema atual. Portanto, funciona tanto como exemplo mínimo executável na sua documentação quanto como corpo de solicitação pronto para envio. Isso é mais seguro que montar um exemplo manualmente, pois um exemplo escrito à mão fica desatualizado quando o schema muda; examples acompanha a mudança.
O mesmo código atende qualquer modelo alterando modelId e não perde a validade quando adicionamos novos modelos. Para gerar uma tabela do catálogo inteiro, percorra os items de GET /api/v1/models?includeSchema=1 e mantenha-os em cache conforme Cache do catálogo.
Texto de ajuda mais longo que description
description é uma frase, dimensionada para um rótulo de formulário. Quando um parâmetro exige mais explicação, o catálogo público oferece uma segunda nota por parâmetro:
curl "https://api.spicyapi.ai/console/v1/catalog/models/MODEL_ID_FROM_CATALOG?locale=en"O registro de um modelo retorna paramNotes, um objeto cujas chaves são os nomes dos parâmetros, escrito em qualquer um dos dez idiomas da documentação via locale. Ele contém o que não cabe em um rótulo: com base em que um valor é medido, qual configuração deixa uma chamada perceptivelmente mais lenta e quais entradas são aceitas pelo schema, mas ainda produzem um resultado abaixo do esperado. Para um parâmetro que aponta para um arquivo hospedado por você, geralmente é o único lugar que informa se buscamos esse arquivo, quando o buscamos e o que acontece se ele for inutilizável.
Há dois limites: paramNotes está no catálogo público, que não exige chave, e não no GET /api/v1/models autenticado; consulte-o separadamente e mantenha-o em cache junto ao schema. Além disso, é texto explicativo, nunca uma regra: inputSchema continua sendo a única referência que determina se uma solicitação é aceita.

