spicyapiDocumentação
Desenvolver com a API
Conteúdo principal

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âmetroSignificado
modalityimage, video, audio ou text
providerCriador 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
taskUma 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
searchTexto presente em qualquer parte do ID ou nome de exibição do modelo, sem diferenciar maiúsculas e minúsculas, com até 128 caracteres
includeSchematrue ou 1 inclui o inputSchema de cada item
includeExamplestrue 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

CampoFinalidade
modelValor exato a enviar como createTask.model, no formato publisher/model/task
familyIdentificador estável da família do produto para agrupar endpoints relacionados
displayNameNome legível deste endpoint
providerCriador do modelo, como o laboratório que o desenvolveu
modality / tasksTipo 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
toolkitFamí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
asynctrue: crie uma tarefa e colete o resultado por consultas de status ou webhook. false: a resposta volta diretamente na chamada
inputSchemaJSON Schema 2020-12 usado para gerar formulários e validar solicitações
examplesEntradas validadas com o schema atual; na lista, só são retornadas quando solicitadas
enabledIndica 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
availableIndica se o modelo pode ser chamado agora. false significa que uma chamada falharia, por exemplo por não haver preço atual
availabilityFase informada: planned, available, preview (campos e saídas ainda podem mudar) ou maintenance (falhas temporárias, com retorno previsto)
pricing / startingPriceSeus preços; veja Como interpretar preços
quantityFieldCampo 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
taskTimeoutSecondsPrazo de execução da plataforma para uma tarefa. Não é a duração da mídia
maxOutputDurationSecondsMaior duração que o modelo pode produzir, obtida de maximum na propriedade duration_seconds; omitido quando não há máximo declarado
badgesMarcadores de capacidades e licença, como commercial_use ou no_watermark. Ignore valores que você não reconhece
relatedModelsAlternativas ou próximos passos selecionados, como IDs de modelos que você pode chamar
version / updatedAtAcompanhamento 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:

CampoSignificado
unitper_image, per_second (de mídia gerada), per_request ou per_1k_tokens
priceSeu preço por unidade em dólares americanos, como string decimal. Já reflete as tarifas da sua conta, que podem variar entre contas
variantConfiguraçõ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
currencySempre USD
regularPrice, offerLabel, offerPercent, offerEndsAtPresentes 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 de quantityField na entrada, ou uma unidade quando quantityField está 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, enquanto unit, quantity, variant e o price da 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 com x-ui.affects_price: true que não é o quantityField nem aparece em x-pricing.variantFields: ele altera o valor sem selecionar uma faixa. Nesses endpoints, trate pricing como 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 multiplique price pelo 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 em price.perMillionTokens no 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 400 e quando o envio de uma tarefa para aquele modelo for recusado.
  • Guarde a version e o updatedAt do 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 schemaNa sua tabela de parâmetros
Uma chave de propertiesNome do parâmetro. Os campos são padronizados entre modelos: um significado, um nome em todos eles
Presença em requiredObrigatório ou opcional
anyOf / allOfObrigatório sob condição. anyOf = forneça pelo menos um destes; em allOf, if → then = se fornecer A, você precisa fornecer B
typeTipo
descriptionTexto de ajuda. Está em inglês e pode ser exibido como está; você não precisa escrever o seu
enumValores aceitos. Quando houver x-ui.enum_labels, use-o para transformar os valores em rótulos legíveis
minimum / maximumIntervalo aceito; x-ui.step define o passo e x-ui.unit, o sufixo (s, px)
minItems / maxItemsEm uma lista, quantidade de entradas aceitas. Uma linha que omite isso não informa ao leitor o limite que ele encontrará
itemsEm 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
defaultValor padrão aplicado quando o campo é omitido
x-ui.orderCrité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.primaryFixar no topo como entrada principal
x-ui.advancedPode ser recolhido em uma seção avançada
x-ui.affects_priceMarcar que afeta o preço; uma mudança de valor exige um novo orçamento
x-ui.widgetControle 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.

Nesta página