Documentação da API
Gere pôsteres a partir de fotos pelo seu próprio sistema. Você compra créditos, cria os temas no painel e consome a geração via API REST. Cada foto gerada com sucesso consome 1 crédito.
Base e autenticação
Todas as rotas ficam sob https://heroshot.me/api/v1 e exigem uma chave de API enviada no cabeçalho Authorization. Gere e gerencie suas chaves no painel, em API. A chave é mostrada uma única vez — guarde com segurança; ela identifica sua conta e o consumo de créditos.
Authorization: Bearer hs_live_suachaveRespostas são JSON. Sempre use HTTPS. Erros retornam { "error": "mensagem" } com o status HTTP correspondente.
Como funciona (assíncrono)
A geração leva cerca de 30 a 60 segundos. Por isso o fluxo é assíncrono:
POST /photosresponde na hora com{ id, status: "processing" }(HTTP 202).- O resultado fica pronto depois. Você descobre de duas formas: consultando
GET /photos/{id}(polling) ou recebendo um webhook quando concluir. - Com o resultado pronto, baixe a imagem pela `resultUrl`.
Gerar uma foto
POST/api/v1/photos
Envie a imagem de uma destas formas: arquivo via multipart/form-data (campo photo), ou JSON com imageUrl (nós baixamos) ou imageBase64. Sempre informe o themeId (veja Listar temas). Limite de 15 MB por imagem.
O campo eventId é opcional: informe o id de um evento seu para a foto entrar na galeria/telão desse evento. Sem eventId, a foto vai para o evento padrão de integrações da sua conta.
Exemplo — upload de arquivo
curl -X POST https://heroshot.me/api/v1/photos \
-H "Authorization: Bearer hs_live_suachave" \
-H "Idempotency-Key: pedido-123" \
-F "photo=@foto.jpg" \
-F "themeId=ID_DO_TEMA"Exemplo — por URL (JSON)
curl -X POST https://heroshot.me/api/v1/photos \
-H "Authorization: Bearer hs_live_suachave" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-123" \
-d '{ "imageUrl": "https://...", "themeId": "ID_DO_TEMA" }'Resposta (202)
{
"id": "9f8e...",
"status": "processing",
"galleryUrl": "https://heroshot.me/p/k7Qm2pX9aB"
}Consultar o resultado
GET/api/v1/photos/{id}
Devolve o status atual. Quando done, traz a resultUrl (arquivo da imagem) e a galleryUrl (página pública de visualização e download — a mesma do QR code, para enviar ao cliente final). Para receber a imagem embutida em base64, adicione ?format=base64.
curl https://heroshot.me/api/v1/photos/9f8e... \
-H "Authorization: Bearer hs_live_suachave"Pronta (done)
{
"id": "9f8e...",
"status": "done",
"themeId": "...",
"resultUrl": "https://heroshot.me/api/files/photos/9f8e.../result.jpg",
"galleryUrl": "https://heroshot.me/p/k7Qm2pX9aB",
"error": null,
"createdAt": "2026-06-11T23:44:47.973Z"
}Enquanto processa, status é processing e resultUrl/galleryUrl são null. Em falha, status é error e error traz o motivo.
Listar temas
GET/api/v1/themes
Temas disponíveis para sua conta (os padrão da plataforma + os que você criou), apenas ativos. Use o id no POST /photos.
curl https://heroshot.me/api/v1/themes \
-H "Authorization: Bearer hs_live_suachave"
{
"themes": [
{ "id": "...", "name": "Faroeste", "kind": "poster",
"orientation": "portrait", "custom": false }
]
}Consultar saldo
GET/api/v1/credits
Saldo da conta: balance é o total; bonus é a parte de cortesia e paid a parte comprada. Os créditos de bônus são consumidos primeiro a cada geração. Sem saldo, o POST /photos responde 402.
curl https://heroshot.me/api/v1/credits \
-H "Authorization: Bearer hs_live_suachave"
{ "balance": 120, "bonus": 10, "paid": 110 }Idempotência
Em qualquer POST /photos, envie o cabeçalho Idempotency-Key com um valor único por pedido. Se a mesma chave chegar de novo (ex.: retry após timeout de rede), devolvemos a mesma foto sem gerar nem cobrar outra vez. Use um identificador do seu lado (id do pedido, UUID).
Webhook
Em vez de ficar consultando, configure uma URL de webhook no painel (em API). Quando uma foto fica pronta (ou falha), enviamos um POST para essa URL:
{
"event": "photo.done",
"id": "9f8e...",
"status": "done",
"resultUrl": "https://heroshot.me/api/files/photos/9f8e.../result.jpg",
"galleryUrl": "https://heroshot.me/p/k7Qm2pX9aB"
}Cada envio vem assinado no cabeçalho heroshot-signature (HMAC SHA-256 do corpo, usando seu segredo do webhook). Valide antes de confiar:
import crypto from 'node:crypto'
const assinatura = req.headers['heroshot-signature']
const esperado = crypto
.createHmac('sha256', SEU_SEGREDO_DO_WEBHOOK)
.update(corpoBrutoDaRequisicao) // o body cru, sem reserializar
.digest('hex')
const valido =
assinatura.length === esperado.length &&
crypto.timingSafeEqual(Buffer.from(assinatura), Buffer.from(esperado))Códigos de erro
| 401 | Chave de API ausente ou inválida |
| 402 | Sem créditos — recarregue para continuar |
| 404 | Foto ou evento não encontrado (ou não é da sua conta) |
| 409 | Tema inexistente ou indisponível para a conta |
| 413 | Imagem acima de 15 MB |
| 422 | Parâmetros faltando ou inválidos |
Boas práticas
- Sempre envie um Idempotency-Key nos POSTs para retries seguros.
- Prefira o webhook ao polling; se fizer polling, espace ~3s entre as consultas.
- Monitore o saldo com `GET /credits` e recarregue antes de zerar.
- Guarde a chave em local seguro (variável de ambiente), nunca no front-end.
- Revogue uma chave comprometida no painel e gere outra — leva segundos.