Saltar para o conteúdo principal
Ao enviar tarefas de geração assíncrona como vídeo / imagem / áudio, você pode incluir uma URL de callback. Assim que a tarefa termina (com sucesso ou falha), enviaremos ativamente o resultado via POST para a sua URL, para que você não precise ficar consultando o tempo todo.

Início rápido

Ao enviar uma tarefa, adicione um campo webhook ao corpo da requisição:
curl -X POST https://seu-dominio-de-acesso/v1/images/generations \
  -H "Authorization: Bearer SUA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "a red apple on a table",
    "size": "1024x1024",
    "webhook": "https://your-server.com"
  }'
Depois que a tarefa terminar, enviaremos uma requisição POST para sua URL + /callback.
Outros endpoints de tarefas assíncronas (vídeo, áudio, etc.) funcionam da mesma forma — basta adicionar o campo webhook ao corpo da requisição.

Regras de URL

O webhook que você fornece é a URL base, à qual anexamos automaticamente /callback:
Seu webhookPara onde realmente enviamos o POST
https://your-server.comhttps://your-server.com/callback
https://your-server.com/apihttps://your-server.com/api/callback
https://your-server.com/api/https://your-server.com/api/callback
Portanto, seu servidor precisa de um endpoint que aceite POST .../callback.

O que você vai receber

O conteúdo enviado é exatamente igual ao que o endpoint “Obter status da tarefa” retorna — você pode processá-lo com a mesma lógica de análise.
{
  "id": "task_01KV7FXR8BEYS1BWHJCT3JMCJ5",
  "status": "completed",
  "progress": 100,
  "created": 1781589029,
  "completed": 1781589058,
  "actual_time": 29,
  "cost": 0.006,
  "credits_cost": 0.06,
  "result": {
    "images": [{ "url": ["https://.../result.png"], "expires_at": 1781675458 }]
  }
}
Para tarefas de vídeo, o resultado fica em result.videos, e para áudio em result.audios.
Só enviamos quando uma tarefa atinge um estado final (completed / failed); não enviamos enquanto está em processamento.

Novas tentativas e deduplicação (importante)

  • Novas tentativas: Se o seu servidor não retornar 2xx em cerca de 10 segundos, ou retornar 5xx, tentaremos novamente de forma automática, até 3 vezes, em intervalos de aproximadamente 10s, 30s e 60s. Se as 3 falharem, desistimos (em cerca de 2 minutos).
  • Sem nova tentativa: Se o seu endpoint retornar 4xx (considerado URL / requisição com problema), desistimos imediatamente, sem tentar de novo.
  • Deduplicação: Normalmente uma tarefa é enviada apenas uma vez. Mas em casos extremos (ex.: um reinício do nosso lado após o envio, mas antes da confirmação) você pode receber envios duplicados. Certifique-se de deduplicar de forma idempotente por id (task_id) para evitar processamento em duplicidade.
Recomendações para o seu endpoint receptor:
1

Retorne 2xx o quanto antes

Aceite e enfileire primeiro, depois processe de forma assíncrona — não nos faça esperar até você terminar o processamento.
2

Deduplique por id

Use id (task_id) como chave de idempotência para evitar processamento em duplicidade.
3

Configure e verifique a assinatura

Em produção, verifique a origem das requisições de callback e rejeite as falsificadas.

Requisitos para a URL de callback

Por segurança, a URL de callback deve atender a:
RequisitoDescrição
Acessível publicamenteNão pode ser um endereço interno / local (ex.: 127.0.0.1, 10.x, 192.168.x serão rejeitados)
Protocolohttp ou https (https recomendado)
PortaUse portas padrão (80 / 443); portas não padrão podem ser bloqueadas
DomínioNão pode apontar para o nosso próprio domínio de serviço
URLs que não atendem a esses requisitos são descartadas (sem envio nem nova tentativa).

Perguntas frequentes

Verifique item por item:
  1. A tarefa realmente terminou? Consulte os detalhes da tarefa — o status está completed / failed (não há envio durante o processamento)?
  2. Sua URL está acessível publicamente? Conseguimos alcançar o seu /callback?
  3. A porta é padrão (80 / 443)? Portas não padrão podem ser bloqueadas por políticas de segurança.
  4. Seu /callback retornou 2xx a tempo? Retornar 4xx é descartado imediatamente.
  5. Você está usando https? O certificado é válido?
Alguns modelos produzem várias imagens de uma vez, então images[].url pode ser um array — basta tratá-lo como um array.
Não. Enviamos apenas uma vez, quando a tarefa finalmente tem sucesso ou falha.

Exemplo mínimo de receptor

Python
from http.server import BaseHTTPRequestHandler, HTTPServer
import json

class H(BaseHTTPRequestHandler):
    def do_POST(self):
        n = int(self.headers.get("Content-Length") or 0)
        body = self.rfile.read(n)
        data = json.loads(body)
        print("Callback de tarefa recebido:", data["id"], data["status"])
        # TODO: deduplicar por id, verificar a assinatura e então processar
        self.send_response(200); self.end_headers()
        self.wfile.write(b'{"ok":true}')

HTTPServer(("0.0.0.0", 443), H).serve_forever()
Retorne 200 o quanto antes e execute sua lógica de processamento de forma assíncrona em segundo plano.