voltar para a página inicial

ArkeFlow

API para desenvolvedores

Conecte o seu ERP, CRM ou site ao WhatsApp da empresa: dispare templates aprovados, mantenha a base de contatos em dia e receba de volta o que acontece — resposta do cliente, status de entrega, pedido de descadastro.

1. Começando

A base de todas as chamadas é https://arkeflow.com/api/v1. Tudo entra e sai em JSON, com Content-Type: application/json. Toda resposta tem um campo ok booleano; quando ele é false, vem também erro com a explicação em português.

Para começar você precisa de duas coisas, as duas obtidas pelo administrador da empresa na tela Administração do ArkeFlow: uma chave de API e, se você quiser receber eventos, a URL do seu sistema cadastrada no webhook de saída.

O acesso à API faz parte dos planos Equipe e Avançado. Nos outros planos as chamadas respondem 403. Isso não é limitação técnica: é o que o plano contratou.

Um detalhe que economiza tempo de depuração: o template tem de estar aprovado pela Meta e sincronizado no ArkeFlow antes de ser usado pela API. Template novo que ainda está em análise responde 409.

2. Autenticação

A chave vai no header Authorization, no formato Bearer. Ela começa com ak_live_ e é mostrada uma única vez, no momento em que é criada — guardamos só o hash, então nem nós conseguimos recuperá-la depois. Se perder, revogue e gere outra.

curl https://arkeflow.com/api/v1/contatos?telefone=54999998888 \
  -H "Authorization: Bearer ak_live_SUA_CHAVE"

Se preferir, a chave também é aceita no header X-Api-Key. Trate-a como senha: ela dá acesso a disparar mensagens cobradas e a ler a base de contatos da empresa. Não a coloque em código de frontend nem em repositório.

3. Limite de chamadas

Cada chave aceita até 120 chamadas por minuto, com teto de 10 por segundo. Passando disso a resposta é 429 com o header Retry-After dizendo quantos segundos esperar. As respostas de sucesso trazem X-RateLimit-Remaining.

Esse limite existe para proteger o cliente de um laço acidental, que gastaria o orçamento dele na Meta em minutos. Um integrador bem-comportado não chega perto dele; se o seu caso de uso precisa de mais, fale com a gente antes de distribuir retry agressivo.

Há um segundo teto, mais apertado, para chaves que não existem. Se você está em homologação e recebe 429 logo nas primeiras tentativas, quase sempre é credencial errada e não volume: confira a chave antes de aumentar o retry.

4. Idempotência

Leia esta seção antes de escrever o retry. Enviar mensagem gasta dinheiro de verdade: a Meta cobra cada template entregue, direto da conta da empresa. Se a sua requisição der timeout e a sua biblioteca repetir o POST, sem cuidado a mensagem sai duas vezes e a cobrança também.

Mande o header Idempotency-Key com um valor único por intenção — o id do pedido no seu sistema serve bem. A primeira chamada executa e nós guardamos a resposta por 24 horas. Qualquer repetição com a mesma chave recebe exatamente a mesma resposta, com o mesmo status e o header X-Idempotencia: repetida, sem enviar nada de novo.

curl -X POST https://arkeflow.com/api/v1/mensagens \
  -H "Authorization: Bearer ak_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-48213-confirmacao" \
  -d '{"telefone":"54999998888","template":"aviso_pedido","variaveis":["Maria","48213"]}'

Três comportamentos que vale conhecer:

  • Mesma chave, corpo diferente → 422. Quase sempre é chave reaproveitada por engano; devolver a resposta antiga esconderia o seu bug.
  • Falha passageira (a Meta recusou, o plano estava sem saldo) → a chave é liberada. Você pode tentar de novo com ela. Só resultado definitivo fica guardado.
  • Sem o header → vale uma guarda automática: o mesmo template, com as mesmas variáveis, para o mesmo número, dentro de 60 segundos, recebe 409. Se a repetição é intencional, mande uma Idempotency-Key nova e ela passa.

5. Enviar mensagem

POST /api/v1/mensagens envia um template aprovado para um telefone. O envio conta na franquia do plano e aparece no painel da empresa como se tivesse saído de lá.

curl -X POST https://arkeflow.com/api/v1/mensagens \
  -H "Authorization: Bearer ak_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-48213-confirmacao" \
  -d '{
    "telefone": "54999998888",
    "template": "aviso_pedido",
    "idioma": "pt_BR",
    "variaveis": ["Maria", "48213"]
  }'

# resposta
{ "ok": true, "id": "wamid.HBgM...", "telefone": "5554999998888", "template": "aviso_pedido", "restante": 1832 }

O telefone pode vir com ou sem o 55 e com ou sem máscara — normalizamos. variaveis aceita lista (posicional, na ordem em que aparecem no template) ou objeto {"nome": "valor"}. Para template com cabeçalho, mídia ou botões com parâmetro, use cabecalho, midia e botoes:

{
  "telefone": "54999998888",
  "template": "boleto_mensal",
  "variaveis": { "nome": "Maria", "valor": "R$ 240,00" },
  "midia": { "tipo": "DOCUMENT", "link": "https://seusistema.com.br/boletos/48213.pdf", "nomeArquivo": "boleto.pdf" },
  "botoes": { "0": { "1": "48213" } }
}

restante diz quantas mensagens ainda cabem na franquia do mês; vem null em plano sem teto. Vale monitorar: quando chega a zero, as chamadas passam a responder 402.

O que a API não faz: enviar texto livre para quem não falou com a empresa nas últimas 24 horas. Essa é regra da Meta, não nossa — fora da janela de 24 h só template aprovado sai. Quem respondeu há pouco é atendido pela tela de atendimento do ArkeFlow.

6. Contatos

POST /api/v1/contatos cria ou atualiza. As tags e os campos são juntados com o que já existe, não substituídos — então mandar o mesmo contato de novo não apaga nada, e por isso esta rota não precisa de Idempotency-Key.

curl -X POST https://arkeflow.com/api/v1/contatos \
  -H "Authorization: Bearer ak_live_SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "telefone": "54999998888",
    "nome": "Maria Silva",
    "tags": ["clientes", "2026"],
    "campos": { "cidade": "Paranhos", "ultimaCompra": "2026-09-30" }
  }'

# 201 quando é novo, 200 quando já existia
{ "ok": true, "novo": true, "contato": { "...": "..." } }

Para consultar: GET /api/v1/contatos?telefone=54999998888. Para registrar descadastro vindo do seu sistema, mande "optOut": true — e respeite-o: contato em opt-out faz o envio responder 403, de propósito.

7. Campanhas

GET /api/v1/campanhas/{id} devolve a situação e os números de uma campanha criada na tela — útil para mostrar o andamento dentro do seu sistema.

curl https://arkeflow.com/api/v1/campanhas/cmp_abc123 \
  -H "Authorization: Bearer ak_live_SUA_CHAVE"

{
  "ok": true,
  "campanha": {
    "id": "cmp_abc123", "nome": "Promoção de outubro", "status": "concluida",
    "template": "promo_outubro",
    "totais": { "fila": 0, "enviadas": 1840, "entregues": 1801, "lidas": 1203, "respostas": 96, "falhas": 39 },
    "taxas": { "entrega": 0.979, "leitura": 0.668, "resposta": 0.053 },
    "iniciadaEm": "2026-10-01T12:00:00.000Z", "concluidaEm": "2026-10-01T12:41:00.000Z"
  }
}

8. Webhook de saída

É o caminho de volta: nós chamamos o seu servidor quando algo acontece. O administrador cadastra a URL em Administração → Webhook de saída e escolhe os eventos. Há um botão que dispara um evento teste na hora, para você conferir a integração sem esperar que alguém responda no WhatsApp.

  • mensagem.recebida — Cliente respondeu (mensagem recebida)
  • mensagem.status — Status de entrega mudou (enviada, entregue, lida, falhou)
  • contato.optout — Contato pediu para sair
  • contato.optin — Contato voltou a aceitar

Chega como POST, com este corpo:

POST /seu/endpoint
Content-Type: application/json
X-Arkeflow-Evento: mensagem.recebida
X-Arkeflow-Entrega: whk_m2h8x1a9k3
X-Arkeflow-Timestamp: 1760000000
X-Arkeflow-Assinatura: sha256=9f86d081884c7d65...

{
  "evento": "mensagem.recebida",
  "em": "2026-10-06T14:22:31.000Z",
  "entregaId": "whk_m2h8x1a9k3",
  "dados": {
    "telefone": "5554999998888",
    "nome": "Maria Silva",
    "texto": "confirmo o pedido",
    "tipo": "text",
    "em": "2026-10-06T14:22:30.000Z",
    "id": "wamid.HBgM...",
    "respondendoA": "wamid.HBgL...",
    "campanhaId": "cmp_abc123",
    "temArquivo": false
  }
}

Três regras do nosso lado que mudam como você escreve o seu endpoint:

  • Responda 2xx em até 5 segundos. Qualquer outra coisa — inclusive redirecionamento, que não seguimos — conta como falha.
  • Repicamos até 6 vezes, com intervalo crescente (1 min, 5 min, 15 min, 1 h, 6 h) e então desistimos. O administrador vê na tela quantas desistiram e qual foi o erro.
  • A entrega é “pelo menos uma vez”. Em reentrega da Meta ou repique nosso, o mesmo evento pode chegar duas vezes. Use o entregaId para descartar o que você já processou — e faça o seu processamento idempotente, pelo mesmo motivo que nós fizemos o nosso.

O jeito mais seguro de escrever o endpoint é: confira a assinatura, grave o evento numa fila sua, responda 200 e processe depois. Processar antes de responder transforma qualquer lentidão sua em repique nosso.

9. Conferir a assinatura

Confira antes de confiar no corpo. A sua URL de webhook é pública; sem a conferência, qualquer um que descubra o endereço pode mandar um mensagem.recebida inventado e fazer o seu sistema agir. A assinatura é um HMAC-SHA256 sobre timestamp.corpo, com o segredo que aparece na tela de administração.

// Node.js (Express) — note o express.raw: o HMAC é sobre o corpo CRU,
// e JSON.parse + JSON.stringify muda o texto e invalida a conta.
const crypto = require('crypto')

app.post('/arkeflow/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.get('X-Arkeflow-Timestamp')
  const assinatura = req.get('X-Arkeflow-Assinatura')
  const corpo = req.body.toString('utf8')

  // 1. O timestamp é recente? Sem isso, uma entrega capturada hoje vale para sempre.
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401)

  // 2. A assinatura bate? Comparação em tempo constante.
  const esperada = 'sha256=' + crypto.createHmac('sha256', process.env.ARKEFLOW_SEGREDO)
    .update(ts + '.' + corpo).digest('hex')
  const a = Buffer.from(assinatura || '')
  const b = Buffer.from(esperada)
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) return res.sendStatus(401)

  // 3. Agora pode confiar.
  const evento = JSON.parse(corpo)
  enfileirarParaProcessar(evento)   // responda rápido; processe depois
  res.sendStatus(200)
})
<?php
// PHP puro
$ts    = $_SERVER['HTTP_X_ARKEFLOW_TIMESTAMP'] ?? '';
$assin = $_SERVER['HTTP_X_ARKEFLOW_ASSINATURA'] ?? '';
$corpo = file_get_contents('php://input');

if (abs(time() - (int) $ts) > 300) { http_response_code(401); exit; }

$esperada = 'sha256=' . hash_hmac('sha256', $ts . '.' . $corpo, getenv('ARKEFLOW_SEGREDO'));
if (!hash_equals($esperada, $assin)) { http_response_code(401); exit; }

$evento = json_decode($corpo, true);
// grave e responda; processe fora da requisição
http_response_code(200);

Se você trocar o segredo na tela, as entregas em voo passam a ser recusadas pelo seu sistema até você atualizar a variável de ambiente. Troque nos dois lados na mesma janela.

10. Códigos de erro

CódigoO que aconteceu e o que fazer
400Corpo inválido: JSON malformado, telefone impossível, variável do template faltando. O campo detalhes diz qual. Não tente de novo sem corrigir.
401Chave ausente, inválida ou revogada. Confira o header Authorization.
402Franquia do plano esgotada, ou assinatura inadimplente/cancelada. Quem resolve é o administrador da empresa; a chave de idempotência é liberada, então você pode repetir depois.
403Três causas: o plano não inclui API, a empresa está suspensa, ou o contato está em opt-out/bloqueio. Opt-out não se contorna — é obrigação legal.
404Template, contato ou campanha não encontrado. Template precisa estar sincronizado no ArkeFlow.
409Template não aprovado pela Meta, chamada idêntica em andamento, ou a guarda automática de 60 s. Para a última, mande uma Idempotency-Key nova.
422A Idempotency-Key já foi usada com um corpo diferente. Use uma chave nova.
429Limite de chamadas. Espere o que diz o Retry-After — com recuo, não em laço.
502A Meta recusou o envio; vem codigoMeta nos detalhes. É passageiro: a chave de idempotência é liberada e você pode repetir.
503A conexão da empresa com a Meta não está configurada. Quem resolve é o administrador.

Dúvida que a página não resolve? Fale com quem administra a conta do ArkeFlow na sua empresa — ou com a gente, pelo canal de suporte do contrato.