Uma API de geração de imagens assíncrona permite que você envie uma solicitação de geração, receba um identificador de job imediatamente e recupere a imagem finalizada mais tarde, em vez de manter uma conexão HTTP aberta. Este tutorial aborda o ciclo de vida do job, quando usar polling versus webhooks e como projetar retries para que um job lento ou com falha não comprometa a experiência do seu produto.
Principais pontos
- A geração de imagens é baseada em jobs, não em request-response, porque a latência de geração (de segundos a dezenas de segundos) não é confiável para ser mantida em uma conexão síncrona.
- O polling é mais simples de construir e depurar; webhooks reduzem a latência e o volume de solicitações, mas exigem um endpoint público, verificação de assinatura e tratamento idempotente de entregas duplicadas.
- A lógica de retry precisa distinguir falhas de submissão, jobs travados e entregas de webhook perdidas; cada uma requer um caminho de recuperação diferente.
- Nomes exatos de endpoints, nomes de campos e formatos de payload de webhook diferem por provedor e pela própria superfície de API da TokenLab. Sempre confirme as especificações atuais em docs.tokenlab.sh antes de colocar em produção.
Por que as APIs de Geração de Imagens são Assíncronas
APIs de completação de texto muitas vezes podem retornar uma resposta na mesma conexão porque a geração de tokens é rápida o suficiente para streaming. Modelos de geração de imagens, sejam baseados em difusão ou autorregressivos, normalmente levam mais tempo e possuem uma latência mais variável dependendo da resolução, da escolha do modelo e da profundidade da fila. Manter uma solicitação HTTP síncrona aberta por dezenas de segundos é frágil: timeouts de cliente, limites de ociosidade de balanceadores de carga e quedas de rede móvel aumentam a chance de perder um resultado concluído pelo qual você já pagou para gerar.
O padrão, utilizado por todos os provedores de geração de imagens, é um modelo de job: você envia uma solicitação e recebe um identificador de job e um status inicial (comumente algo como queued ou processing). Você então faz o polling de um endpoint de status ou recebe uma notificação via webhook quando o job atinge um estado terminal, e busca as URLs da imagem final ou dados binários em uma chamada separada.
A TokenLab oferece acesso a múltiplos modelos de imagem, incluindo a família Nano Banana 2, Nano Banana Pro e Nano Banana 2 Lite, GPT Image 2, Reve 2.0 e MAI-Image-2.5, através de uma única superfície de API. Veja o diretório de modelos de imagem para a lista atual e o guia de tarefas de geração de imagem assíncrona para o comportamento específico dos endpoints de job da TokenLab. O padrão geral abaixo se aplica independentemente de qual modelo subjacente você chamar, mas os nomes exatos dos campos e valores de status estão documentados em docs.tokenlab.sh e devem ser verificados lá, em vez de presumidos a partir deste artigo.
O Ciclo de Vida do Job: Submeter, Polling, Recuperar
Em um nível conceitual, um job de imagem assíncrono tem três estágios:
- Submeter: POST com um prompt e parâmetros, receba um ID de job e um status inicial.
- Verificar status: faça o polling de um endpoint GET usando o ID do job ou aguarde um evento de webhook.
- Recuperar saída: uma vez que o status seja terminal (succeeded ou failed), busque a(s) URL(s) da imagem ou detalhes do erro.
Aqui está um padrão ilustrativo de polling em Python. Trate os caminhos dos endpoints e nomes de campos como espaços reservados; confirme o formato atual do endpoint de job da TokenLab na documentação da API antes de usar isso em produção.
import time
import requests
API_BASE = "https://api.tokenlab.sh/v1" # verifique a URL base atual em docs.tokenlab.sh
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def submit_image_job(prompt, model="nano-banana-2"):
resp = requests.post(
f"{API_BASE}/images/jobs",
headers=HEADERS,
json={"prompt": prompt, "model": model, "idempotency_key": generate_key()},
)
resp.raise_for_status()
return resp.json()["job_id"]
def poll_job(job_id, max_wait_seconds=120, interval=2, backoff=1.5):
waited = 0
while waited < max_wait_seconds:
resp = requests.get(f"{API_BASE}/images/jobs/{job_id}", headers=HEADERS)
resp.raise_for_status()
data = resp.json()
if data["status"] in ("succeeded", "failed"):
return data
time.sleep(interval)
waited += interval
interval = min(interval * backoff, 15)
raise TimeoutError(f"Job {job_id} did not complete within {max_wait_seconds}s")
job_id = submit_image_job("a studio product shot on white background")
result = poll_job(job_id)
if result["status"] == "succeeded":
image_url = result["output"]["url"]
else:
print("job failed:", result.get("error"))
O idempotency_key na chamada de submissão é importante: se um erro de rede ocorrer após o job ter sido criado, mas antes que seu cliente receba o ID do job, repetir a chamada de submissão com a mesma chave deve retornar o job existente em vez de criar uma geração duplicada. Confirme se e como o endpoint de job da TokenLab suporta chaves de idempotência na documentação atual, já que este é um padrão comum, mas não universal, entre os provedores.
Polling vs. Webhooks: Tradeoffs
Ambas as abordagens são válidas; a escolha certa depende do seu padrão de tráfego e infraestrutura.
O Polling é mais simples de implementar e testar localmente, não requer endpoint público e funciona bem para cargas de trabalho de baixo volume ou em lote, onde alguns segundos extras de latência não importam. Suas desvantagens são um limite mínimo de latência igual ao seu intervalo de polling e um volume desnecessário de solicitações se você fizer polling de forma muito agressiva em jobs de longa duração.
Os Webhooks enviam uma notificação para o seu servidor quando um job muda de estado, o que reduz a latência e diminui o desperdício de chamadas de verificação de status. O custo é operacional: você precisa de um endpoint HTTPS publicamente acessível, verificação de assinatura para confirmar que o payload realmente veio do provedor e tratamento para entregas duplicadas ou fora de ordem.
A documentação de eventos de webhook da OpenAI descreve o formato geral deste padrão para operações assíncronas: seu endpoint recebe um evento com um tipo e um identificador de objeto, e a prática recomendada é tratar o payload do webhook como uma notificação para buscar o estado atual do recurso via API, em vez de confiar no corpo do webhook como a fonte final da verdade. Esse padrão de "pull-after-push" vale a pena ser adotado independentemente de qual provedor de imagem você esteja integrando, pois protege você caso um payload de webhook seja truncado, atrasado ou entregue mais de uma vez.
Implementando Webhooks com Segurança
Se você escolher webhooks para a conclusão de jobs de imagem, as seguintes práticas reduzem a chance de falhas silenciosas:
- Verifique a assinatura em cada solicitação de webhook recebida antes de processá-la. Rejeite qualquer coisa que não corresponda e registre as rejeições separadamente do tráfego normal para que você possa identificar rapidamente um segredo mal configurado.
- Responda rápido, processe depois. Confirme o recebimento do webhook com um status 200 assim que validá-lo, então envie o trabalho real (buscar a imagem, gravar no armazenamento, notificar seu usuário) para um job ou fila em segundo plano. Os provedores geralmente tentam reenviar o webhook se não receberem uma resposta 2xx em tempo hábil, o que pode causar processamento duplicado se o seu handler for lento e síncrono.
- Desduplique pelo ID do job. Armazene os IDs de jobs processados (ou um hash do evento) para que uma entrega repetida não gere uma notificação ou reprocesse uma gravação de arquivo.
- Busque novamente o recurso usando o ID do job do payload do webhook, em vez de confiar nas URLs de saída incorporadas como necessariamente finais, consistente com o padrão de "pull-after-push" descrito acima.
Um esboço de handler mínimo:
from flask import Flask, request, abort
app = Flask(__name__)
processed_job_ids = set() # use um armazenamento real em produção
@app.route("/webhooks/image-jobs", methods=["POST"])
def handle_webhook():
if not verify_signature(request):
abort(401)
event = request.get_json()
job_id = event.get("job_id") or event.get("data", {}).get("id")
if job_id in processed_job_ids:
return "", 200 # já processado, confirme e ignore
enqueue_background_task("fetch_and_store_image", job_id)
processed_job_ids.add(job_id)
return "", 200
Verifique os nomes exatos dos eventos de webhook, a estrutura do payload e o cabeçalho de assinatura usados para a conclusão de jobs de imagem na documentação atual do provedor e, separadamente, no suporte a webhooks da própria TokenLab conforme descrito em docs.tokenlab.sh, já que esses detalhes são específicos do provedor e podem mudar.
Design de Retry: Três Classes de Falha
Jobs de imagem assíncronos falham de três maneiras distintas, e cada uma precisa de seu próprio tratamento:
- Falhas de submissão: o POST para criar um job retorna um 4xx ou 5xx. Para 5xx e erros de rede, tente novamente com exponential backoff e jitter, reutilizando a mesma chave de idempotência para não criar jobs duplicados. Para erros 4xx (prompt ruim, modelo inválido, cota excedida), tentar novamente sem alterar a solicitação falhará novamente; exiba o erro para o chamador.
- Jobs travados: um job permanece em um status não terminal muito além do tempo de geração esperado. Defina um limite máximo de espera por modelo (o tempo de geração varia conforme o modelo e a resolução) e trate os jobs que o excederem como falhos para os propósitos da sua aplicação, mesmo que o provedor ainda não os tenha marcado formalmente como falhos. Registre isso separadamente, pois uma taxa crescente de jobs travados geralmente sinaliza um incidente do lado do provedor.
- Entregas de webhook perdidas: seu endpoint estava fora do ar ou a entrega foi descartada, e nenhum evento chegou. É por isso que vale a pena manter um fallback de polling mesmo em um design focado em webhooks: uma varredura periódica que verifica o status de qualquer job com mais de alguns minutos sem um estado terminal captura jobs cujo webhook falhou silenciosamente ao chegar.
Checklist de Decisão
Use este checklist ao decidir como configurar a conclusão de jobs para uma funcionalidade de geração de imagens.
| Cenário | Abordagem recomendada | Por que |
|---|---|---|
| Baixo volume, ferramenta interna ou script em lote | Polling | Mais simples de construir; sem necessidade de endpoint público |
| Funcionalidade voltada ao usuário onde a latência importa | Webhooks, com varredura de fallback via polling | Menor latência; o fallback captura entregas perdidas |
| Alto volume de jobs (milhares/dia) | Webhooks | Evita volume excessivo de solicitações de verificação de status |
| Sem capacidade de expor um endpoint HTTPS público | Polling | Webhooks exigem um receptor acessível |
| Necessidade de prevenção rigorosa de duplicatas | Chaves de idempotência na submissão, desduplicação por ID de job no recebimento | Protege contra submissões repetidas e entregas duplicadas de webhook |
| Múltiplos modelos de imagem em um pipeline | Normalize o status do job e o tratamento de erros em sua própria camada | Provedores subjacentes (veja a comparação de modelos de imagem) não compartilham taxonomias de status idênticas |
Limitações
Este artigo descreve um padrão geral para APIs de jobs de imagem assíncronos e não afirma caminhos exatos de endpoints, nomes de campos, valores de timeout ou nomes de eventos de webhook para a TokenLab ou para qualquer provedor de modelo subjacente específico além do que foi citado acima. Vocabulários de status de job, cabeçalhos de retry-after e esquemas de assinatura de webhook variam entre provedores e podem mudar com o tempo; trate o código neste artigo como ilustrativo, não como código de produção pronto para copiar e colar, e confirme os formatos atuais de solicitação e resposta em docs.tokenlab.sh antes de colocar em produção. Este artigo não cobre preços, limites de taxa ou garantias de throughput para nenhum modelo específico.
FAQ
Devo sempre usar webhooks em vez de polling? Não. Webhooks reduzem a latência e o volume de solicitações com um custo operacional maior. Para casos de uso de baixo volume ou internos, o polling é frequentemente a escolha mais simples e igualmente confiável. Muitos sistemas de produção usam webhooks como o caminho principal com uma varredura de polling periódica como fallback.
Como evito gerações de imagem duplicadas em caso de retry? Use uma chave de idempotência na solicitação de submissão do job para que um POST repetido após uma falha de rede retorne o job existente em vez de criar um novo. Confirme se o endpoint de criação de job do seu provedor suporta isso antes de confiar nele.
O que acontece se meu endpoint de webhook estiver fora do ar quando o job for concluído? O comportamento depende do provedor; alguns tentam reenviar a entrega por um período, outros não garantem o reenvio. Uma varredura de polling periódica para jobs com mais de alguns minutos sem um status terminal é uma salvaguarda prática, independentemente da política de retry do provedor.
Se você está construindo uma funcionalidade de geração de imagens e deseja comparar o acesso baseado em job entre múltiplos modelos em uma única API, revise o diretório de modelos de imagem e o guia de tarefas de geração de imagem assíncrona, então Comece com a documentação da API da TokenLab para confirmar os detalhes atuais de endpoint e webhook para sua implementação.
Fontes
Preço observado em 2026-07-14
- OpenAI webhook eventsObservado em 2026-07-14
- TokenLab API documentationObservado em 2026-07-14
- TokenLab model directoryObservado em 2026-07-14



