Central de ajudaAdminQuem decide
API de Disparo Outbound: envie mensagens proativas pelo seu backend
Enfileire envios WhatsApp/Telegram com o mesmo worker da página Disparos. Auth, envio unitário/lote, templates Meta, opt-outs, limites e recibos.
A API de Disparo Outbound permite que o seu backend enfileire mensagens proativas nos canais conectados do workspace — a mesma fila, ritmo, lista de supressão e trilha de auditoria da página Disparos no console. Use a partir de CRMs, sistemas de pedido e agendadores quando precisar de envios disparados no servidor em escala.
URL base e autenticação
https://concierge.bentokit.ai/api/integrations/concierge/v1/dispatch- Authorization: Bearer czsk_… (chave do workspace em Acesso à API → Chaves)
- Cada chamada fica no escopo do workspace da chave
- Envios são assíncronos: valida e enfileira agora; um worker com ritmo entrega depois
- Cabeçalho opcional Idempotency-Key (ou idempotencyKey no body) evita duplicar retentativas
curl -sS -X POST "https://concierge.bentokit.ai/api/integrations/concierge/v1/dispatch" \
-H "Authorization: Bearer czsk_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-4958343-shipped" \
-d '{ "channelId": "whatsapp-2", "to": "5521999999999", "text": "Olá!" }'Gêmeo no console
- Criar uma chave de API
Acesso à API → Chaves. Copie o segredo uma vez (czsk_…). Guarde só no servidor.
- Conectar um canal com envio proativo
WhatsApp Cloud, WhatsApp Pessoal, Telegram, etc. O canal precisa aceitar envio proativo (a página Disparos mostra as rotas prontas).
- Ensaiar em Disparos (opcional)
Monte um envio único no console primeiro. A API usa o mesmo worker e a mesma lista de supressão.
- Chamar a API pelo backend
Prefira templates aprovados do provedor no WhatsApp Cloud oficial. Texto livre funciona nos canais que permitem.
Listar disparos recentes
GET / com status, batchId e limit opcionais (1–500, padrão 50) devolve as linhas recentes do workspace. Status: queued, sending, accepted, sent, delivered, read, failed, blocked, expired, cancelled.
Enviar uma mensagem
POST / devolve 202 com { dispatch } quando enfileirado, 409 quando bloqueado (ex.: opt-out), ou { dispatch, deduped: true } quando a chave de idempotência já existe. Exatamente um formato de conteúdo é obrigatório.
{
"channelId": "whatsapp-2",
"to": "5521999999999",
"ttlSeconds": 86400,
"text": "…",
"templateId": "tpl_…",
"variables": { "name": "Ana" },
"providerTemplate": {
"name": "order_update",
"language": "pt_BR",
"parameters": ["Ana", "4958343"]
},
"idempotencyKey": "chave-estavel-opcional"
}- text: texto livre (canais que permitem free-form)
- templateId + variables: mensagem salva do workspace com placeholders {{nome}}
- providerTemplate: template aprovado estilo Meta (obrigatório no WhatsApp Cloud oficial)
- ttlSeconds: 60–604800 (padrão 86400). Expirado na fila é descartado, nunca enviado atrasado
- Omita channelId só se houver exatamente um canal de saída; senão envie o id ou receba channel_ambiguous
Envio em lote
POST /batch aceita os mesmos formatos com recipients: [{ to, variables? | parameters? }]. Até 500 destinatários por requisição. Idempotência de lote no tenant evita enfileirar duas vezes em retry.
{
"channelId": "whatsapp-2",
"providerTemplate": {
"name": "order_update",
"language": "pt_BR",
"parameters": ["PLACEHOLDER"]
},
"recipients": [
{ "to": "5521999999999", "parameters": ["Ana", "4958343"] },
{ "to": "5521888888888", "parameters": ["Bruno", "4958344"] }
],
"ttlSeconds": 86400
}Destinatários a partir de leads
GET /recipients?channelId=…&q=…&limit=… projeta leads capturados como destinatários de telefone daquele canal (id normalizado, nome, telefone, e-mail, origem/status, optedOut). Só canais phone-kind; outros devolvem unsupportedKind: true até existir mapeamento de chat-id.
Mensagens salvas (templates do workspace)
- GET|POST /templates — listar ou criar corpos com placeholders {{variavel}}
- GET|PUT|DELETE /templates/:id — ler, atualizar, apagar
- Só em canais que permitem free-form / mensagem salva
Templates do provedor (Meta)
- GET /channels/:channelId/templates[?includeUnavailable=true] — aprovados por padrão, ou todos os status
- POST /channels/:channelId/templates — enviar novo template se o canal declarar templateManagement
- DELETE /channels/:channelId/templates/:name — apaga todas as línguas daquele nome (semântica do provedor)
{
"name": "order_update",
"language": "pt_BR",
"category": "UTILITY",
"bodyText": "Olá {{1}}, seu pedido {{2}} está a caminho.",
"bodyExamples": ["Ana", "4958343"],
"footerText": "BentoKit"
}Falhas de validação devolvem 400 com códigos estáveis (invalid_template_name, template_placeholders_not_sequential, template_examples_mismatch, …). Novos templates costumam ficar pending até a Meta revisar.
Lista de supressão (opt-outs)
- GET /optouts — listar destinatários bloqueados
- POST /optouts — { to, channelId? | channelKind? } bloqueia antes da fila
- DELETE /optouts?to=…&channelKind=… — remover supressão
- Honre a mesma lista nos seus sistemas para não recontatar quem saiu
Limites e erros
- Texto do corpo ~4000 caracteres no máximo
- Lote máximo 500 destinatários
- Teto diário padrão 1000/workspace (env CONCIERGE_DISPATCH_DAILY_CAP) → 429 daily_dispatch_cap
- Limite de rajada de enfileiramento (padrão 120/min) → 429 rate_limited
- 4xx comuns: channel_not_found, no_dispatch_channel, channel_ambiguous, template_or_text_required, provider_template_not_approved, recipient_opted_out (blocked)
- 402 plan_feature_missing quando outbound_campaigns não está no plano
Recibos de entrega de volta
Se o seu sistema precisa saber quando a mensagem foi aceita, entregue ou falhou, assine dispatch.* em Acesso à API → Webhooks (opcional). A maioria das integrações de CRM pode ignorar esses eventos e consultar GET /.
- Chave de API só no servidor
- WhatsApp oficial usa só providerTemplate aprovado
- Idempotency-Key em todo envio de produção que possa retentar
- Lista de supressão checada ou espelhada no CRM
- TTL definido para não enviar promo atrasada se o canal ficar fora