sem chave salva

Autenticação

Authorization: Bearer sk_live_... ou sk_test_.... test roda o mesmo modelo e custa o mesmo — o que muda é a cota, separada da de produção.

A chave que você cola acima fica só no localStorage deste navegador e vai direto para /v1/...: esta página não tem servidor por trás guardando nada.

Imagens de entrada

Todo campo de imagem aceita uma das duas formas:

{ "url": "https://cdn.loja/peca.jpg" }              // https, público, jpeg ou png
{ "base64": "/9j/4AAQ...", "mime_type": "image/jpeg" }  // ou data URI completo
  • Teto de 15 MB por imagem e 40 MB por request. Base64 infla 33%.
  • https, só image/jpeg e image/png.
  • URL que resolve para endereço privado é recusada, e redirect não é seguido.

POST /v1/mannequin

Entra a foto de uma peça — vestida, no cabide, na sala. Sai uma imagem: a peça sobre uma forma de acrílico transparente, em fundo de estúdio, com volume de corpo.

CampoTipoPadrão
imageimagem
body_formfeminino · masculino · neutroneutro
response_formaturl · base64url
webhook_urlstring

POST /v1/try-on

Veste uma pessoa em até 5 peças. A ordem do array é contrato: a n-ésima imagem é a n-ésima peça.

CampoTipoPadrão
personimagem
garments[].namestring, obrigatório
garments[].imageimagem
garments[].formon_mannequin · alone · on_model · rawraw
prepare_garmentsbooleanfalse

Recomendação: peça vinda de /v1/mannequin usa form: "on_mannequin" — é a melhor entrada medida, e não paga preparo. raw só com prepare_garments: true.

GET /v1/jobs/{id}

status: queued · running · succeeded · failed · expired. Enquanto não fecha, output é null.

Com retenção zero (padrão), a purga apaga o job cerca de 60s depois de fechar — baixe a imagem assim que status virar succeeded.

GET /v1/usage

{ "credits_used": 412, "credits_included": 3000, "period_start": "2026-08-01",
  "by_kind": { "tryon_brief": 40, "tryon_render": 240 }, "plan": "starter", "env": "live" }

Erros

{ "error": { "code": "content_blocked", "message": "…", "request_id": "…", "detail": "IMAGE_SAFETY" } }
HTTPcodeQuando
400invalid_requestcampo ausente, formato errado, mais de 5 peças
401unauthorizedchave ausente, inválida ou revogada
402quota_exceededcréditos do ciclo esgotados
404not_foundjob inexistente ou de outro projeto
413payload_too_largeimagem acima de 15 MB, corpo acima de 40 MB
422content_blockedo modelo recusou por política de conteúdo
429rate_limited / too_many_concurrent_jobsrespeite Retry-After
502upstream_errorfalha do gerador, já retentada
504upstream_timeouta geração excedeu o tempo limite

request_id aparece em toda resposta de erro — mande-o junto ao reportar.

Webhook

webhook_url recebe um POST quando o job fecha, assinado em X-Provador-Signature: t=<unix>,v1=<hex> (HMAC-SHA256 sobre "{timestamp}.{corpo}").

Uma tentativa só, e o polling é o contrato: cliente que só confia no webhook perde o desfecho sempre que o endpoint dele estiver de pé mas errado.

Retenção

Padrão do projeto: zero hora. Entrada e saída são apagadas assim que o job fecha e você busca o resultado. Retenção maior existe por contrato, nunca por campo no request.