Skip to main content
Por padrão, a API só responde depois que o WhatsApp executa o comando. Um envio de mídia pesada, por exemplo, segura o request até a mensagem sair. Com async: true, a API enfileira o comando, responde na hora com um commandId e executa em segundo plano. O resultado chega de duas formas, ambas com o mesmo payload:
  • Webhook command.result: a API avisa seu sistema quando o comando termina. É o canal de entrega garantida.
  • Consulta pelo commandId: GET /api/v1/commands/{commandId}, útil para depuração ou como complemento. O resultado expira depois de cerca de 1 hora.

Fluxo

1

Envie o comando com async: true

2

Guarde o commandId da resposta

A API responde 200 imediatamente, antes de executar o comando:
success: true aqui significa só que o comando entrou na fila. Ainda não diz se ele deu certo.
3

Receba o resultado no webhook

Quando o comando termina, com sucesso ou falha, a API envia um evento command.result com o mesmo commandId.

Ativando o modo assíncrono

Envie async no corpo (JSON) ou na query string, nas rotas GET. O campo aceita booleano (true) ou string ("true" ou "1"). Ausente ou false, o comando é síncrono como sempre.
Sessões da API Oficial (cloud_api) ignoram o async e sempre respondem de forma síncrona: o envio passa direto pela Meta, sem fila.

Resposta do enfileiramento

string
required
UUID do comando. É a chave para correlacionar com o webhook e para consultar o status.
boolean
required
Sempre true nesta resposta: o comando foi aceito na fila.
string
required
Sempre "queued".
string
required
Sempre "Command queued".
string
required
Momento do enfileiramento em ISO 8601 (UTC).
As rotas de envio de mensagem também devolvem sessionId, to e messageType. Se a API não conseguir enfileirar, ela responde com erro e o comando não é executado. Nesse caso é seguro tentar de novo.

Rotas compatíveis

Webhook command.result

Configuração

O webhook de comandos é de conta: uma URL recebe o resultado de todos os comandos assíncronos de todas as sessões da conta. Ele é separado dos webhooks de eventos de cada sessão do WhatsApp. No painel, acesse Integrações → Webhook de Comandos e informe:
  • URL: endpoint https:// que vai receber os eventos.
  • Secret (opcional, recomendado): ativa a assinatura X-DAPI-Signature.
  • Ativo: sem isso, nenhum evento é enviado.
Também dá para configurar pela API:
GET /api/v1/account/webhooks lista a configuração atual, com hasSecret no lugar do secret.
Sem webhook de comandos configurado e ativo, o comando assíncrono executa normalmente, mas o resultado não é enviado a lugar nenhum. Ele só fica disponível na consulta pelo commandId, durante a janela de retenção.

Envelope

string
required
Sempre "command.result".
string
required
Sempre "command".
string
required
Momento em que o webhook foi gerado, em ISO 8601 (UTC).
object
required
Resultado do comando.

Exemplo de falha

Um comando que executou e falhou, ou que estourou o tempo limite, também gera command.result, com success: false:
O texto de error vem do WhatsApp ou da camada de execução e pode mudar. Use success para decidir o fluxo e trate error como mensagem de log.

Headers

Validando a assinatura

Calcule o HMAC sobre o corpo bruto recebido, não sobre o JSON re-serializado, e compare com o header usando comparação de tempo constante:

Garantias de execução e entrega

Cada comando assíncrono gera exatamente um command.result: com success: true se deu certo ou success: false se falhou ou estourou o tempo limite.
Se o comando falhar, a API não tenta de novo: muitos comandos, como envio de mensagem, não podem ser repetidos sem risco de duplicar. Reenviar fica a seu critério, depois de ler o error.
O webhook sai por uma fila durável. Seu endpoint precisa responder 2xx em até 30 segundos. Fora disso, a entrega é repetida com backoff exponencial (15 s, depois 30 s), em até 3 tentativas no total.
  • 404 ou 410 encerram as tentativas na hora: o endpoint é tratado como inexistente.
  • Um endpoint que falha repetidamente tem a entrega suspensa por um tempo (circuit breaker), para não acumular tentativas inúteis.
Por causa da retentativa, o mesmo command.result pode chegar mais de uma vez. Isso acontece, por exemplo, se seu endpoint processar o evento mas responder depois de 30 segundos. Trate o commandId como chave de idempotência e ignore repetições.
Boas práticas no endpoint:
  • Responda 200 assim que validar a assinatura e processe o evento depois, em fila própria.
  • Guarde o commandId no momento do envio, junto da entidade do seu sistema (pedido, conversa, notificação), para casar o resultado depois.
  • Não dependa da ordem de chegada dos webhooks. Comandos rodam em paralelo e podem terminar em ordem diferente da de envio.

Consulta pelo commandId

GET /api/v1/commands/{commandId} mostra o estado atual do comando, se ainda está na fila, executando ou já terminou, e traz o mesmo payload do webhook em result. Detalhes em Consultar comando assíncrono.
O resultado fica consultável por cerca de 1 hora após a execução (24 horas se o worker falhar). Depois disso a consulta responde 404.

Ordem de entrega (sequential)

Comandos assíncronos rodam em paralelo. Dois envios seguidos para o mesmo contato podem chegar fora de ordem: uma imagem pesada pode sair depois do texto enviado logo em seguida. Para envios de mensagem, adicione sequential: true junto de async: true. Os envios para o mesmo destinatário saem um de cada vez, na ordem em que chegaram na API. Cada um continua gerando seu próprio command.result. Veja Envio assíncrono em ordem.

Erros comuns