Trabalhando com um agente de IA? Baixe a documentação completa como arquivo Markdown para usar como contexto.
Baixar .md completoUm canal é um ativo Meta conectado — um número de WhatsApp, uma conta do Instagram ou uma Página do Facebook — pelo qual você envia e recebe mensagens. Esta página cobre como conectar, gerenciar e reconectar canais. Os schemas de campos estão na Referência da API.
Antes de conectar qualquer canal — WhatsApp, Instagram ou Facebook Messenger — garanta que as condições abaixo sejam atendidas. Elas valem igualmente para o fluxo do Portal e o fluxo da API; se uma das duas primeiras faltar, a Meta interrompe o popup de OAuth antes que um canal possa ser criado.
10.Use isto para conectar seus próprios canais, sem necessidade de código.
A webhook URL deve ser uma URL HTTPS absoluta e acessível pela Fiwano. Portas explícitas de 1 a 65535 são suportadas; credenciais embutidas e fragmentos de URL não são.
Use isto quando sua aplicação conecta canais em nome dos seus usuários finais.
Passo 1 — Cadastre seu redirect URI na whitelist. Por segurança, o usuário só pode ser
redirecionado de volta a uma URL que você tenha pré-registrado para a sua chave de API.
Registre a(s) URL(s) onde os usuários chegam após o OAuth (coringas são permitidos, ex.:
https://*.example.com/callback):
curl -X POST https://fiwano.com/api/v1/redirects \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"uri_pattern": "https://yourapp.com/callback"}'
Os padrões de redirect URI devem usar HTTPS e não podem apontar para localhost nem
para um endereço de loopback. Portas explícitas de 1 a 65535 são suportadas,
inclusive portas HTTPS não padrão, como https://yourapp.com:4426/callback. URIs
exatos são mais seguros e recomendados. Quando um curinga for necessário, ele pode
aparecer no caminho/query ou como um rótulo completo mais à esquerda do hostname
(*.example.com), mas não pode substituir todo o hostname, parte de um rótulo ou
a porta. Credenciais embutidas, fragmentos de URL e as chaves de query reservadas
code, status, channel_type e error são rejeitados.
Para associar um fluxo de setup ao tenant ou administrador autenticado, gere um
nonce opaco, de alta entropia e uso único, armazene-o no servidor junto com esse
contexto e coloque somente o nonce no redirect URI. Cadastre um padrão restrito,
como https://yourapp.com/callback?state=*, e solicite a setup URL com
https://yourapp.com/callback?state=NONCE_BASE64URL. A Fiwano preserva state e
acrescenta seus próprios parâmetros, por exemplo
?state=NONCE_BASE64URL&code=...&status=success&channel_type=whatsapp. Use um
valor URL-safe e não coloque IDs de tenant/usuário nem outros dados sensíveis
diretamente na URI.
Você os gerencia com GET /api/v1/redirects e DELETE /api/v1/redirects/{id}.
Passo 2 — Solicite uma setup URL. Passe um dos seus redirect URIs da whitelist. A
URL é válida até o expires_at retornado na resposta — abra-a em um navegador ou popup
para o usuário:
curl -X POST https://fiwano.com/api/v1/channels/setup-url \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"channel_type": "whatsapp", "redirect_uri": "https://yourapp.com/callback"}'
O mesmo endpoint também reconecta canais; não existe uma API de reconnect
separada. Se o usuário conectar uma conta Meta que já é um canal seu,
exchange-code retorna esse channel_id existente — veja
Reconectando um canal.
A requisição é recusada com 402 quando a conta não tem assinatura ativa, e com
409 quando todos os slots de assinatura daquele tipo de canal já estão ocupados
e nenhum dos canais que os ocupam pode ser reconectado por este fluxo. O corpo do
409 é estruturado: detail.code é no_free_slot e detail.occupied_by lista
os canais que ocupam os slots — veja slots de assinatura
para saber como liberar um.
Passo 3 — O usuário conclui o OAuth da Meta. Após a aprovação, o usuário é
redirecionado ao seu redirect_uri com um parâmetro code de uso único:
https://yourapp.com/callback?code=abc123...
Em caso de falha, o redirect leva dois query params — ramifique sua lógica apenas no
error:
| Query param | Como usar |
|---|---|
error |
Código legível por máquina. Ramifique nisto. access_denied — o usuário cancelou ou não concluiu o diálogo da Meta. slot_occupied — o usuário conectou uma conta Meta diferente da que ocupa o slot da sua assinatura; message indica o canal a reconectar ou liberar (veja slots de assinatura). session_expired — a setup URL expirou antes de o fluxo terminar; solicite uma nova. setup_failed — qualquer outra coisa que interrompeu o setup (ex.: nenhuma conta do Instagram Business estava acessível com as permissões concedidas). |
message |
Explicação legível por humanos em inglês, codificada em URL, segura para exibir ao usuário. Formato livre e pode mudar — nunca faça parse ou ramifique no texto dela. |
Exemplo de redirect de falha:
https://yourapp.com/callback?error=setup_failed&message=We%20couldn%27t%20access%20any%20Instagram%20Business%20account...
Passo 4 — Troque o code. Em até 5 minutos (uso único), troque o code pelo canal. Você pode configurar o webhook na mesma chamada:
curl -X POST https://fiwano.com/api/v1/channels/exchange-code \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"code": "abc123...",
"webhook_url": "https://yourapp.com/webhooks/meta",
"webhook_events": ["message.received", "message.delivered", "message.failed"]
}'
A resposta retorna seu channel_id (guarde-o — toda outra chamada o utiliza). Quando
você define webhook_url e não fornece um webhook_secret, a Fiwano gera um
automaticamente e o retorna aqui. Ele é retornado apenas nesta resposta — o GET
nunca o mostra de novo — então guarde-o para verificar as assinaturas dos webhooks
(Segredo do webhook). Todos os campos exceto code são opcionais e
podem ser definidos depois via PATCH /api/v1/channels/{id}.
A entrega de webhooks é opt-in por canal: por padrão nenhum evento é entregue.
Você escolhe o que recebe definindo webhook_events — na chamada de conexão, no Portal,
ou depois via PATCH /api/v1/channels/{id}. Até fazer isso, seu endpoint não recebe nada.
A maioria dos eventos existe em todos os canais; message.sent é só do WhatsApp e
conversation.referral só do Instagram e do Facebook. A lista completa com os
payloads está na página Recebendo Mensagens.
Um evento que você listar e que não seja válido para o tipo de canal é ignorado, não é
um erro.
Um evento tem um ajuste extra: message.echo (cópias de mensagens que sua empresa envia
fora da Fiwano) entrega apenas a mensagem por padrão. Defina o campo booleano
echo_statuses do canal — na chamada de conexão, via PATCH /api/v1/channels/{id} ou no
Portal — para receber também os status delivered/read das mensagens ecoadas pelos seus
eventos de status habituais. Detalhes: message.echo.
Seu endpoint cumpre a outra metade desse contrato. Uma vez habilitados os eventos, a
Fiwano faz POST de cada um para seu webhook_url, e seu endpoint precisa responder com
HTTP 2xx em até 5 segundos; caso contrário, a Fiwano tenta novamente e envia e-mail para
você — veja Política de novas tentativas. Por
isso, habilite apenas os eventos que você realmente trata e retorne 2xx assim que
aceitar o payload (faça o trabalho mais lento depois).
O webhook_secret é a chave HMAC que a Fiwano usa para assinar as entregas de
webhook, para que seu endpoint possa confirmar que a requisição realmente veio da
Fiwano e não foi alterada no caminho. Quando um canal tem um segredo, cada entrega traz
um cabeçalho X-Webhook-Signature: sha256=<hmac> — veja
Verificando assinaturas para o trecho de verificação. Um canal sem
segredo recebe entregas sem assinatura.
Como um segredo aparece pela primeira vez difere conforme você conecta — e este é o único ponto em que o Portal e a API se comportam propositalmente de forma diferente:
webhook_url e o canal ainda não tem segredo, a
Fiwano gera um automaticamente (hex de 64 caracteres) e o retorna na resposta de
exchange-code / PATCH /api/v1/channels/{id} — ou seja, canais conectados via API
são assinados por padrão. Para usar um valor específico, forneça o seu próprio
webhook_secret (no máximo 64 caracteres) nessa mesma chamada.Lendo de volta. O valor só é retornado no momento em que é definido ou alterado —
na revelação única do Portal, ou na resposta da chamada exchange-code ou
PATCH /api/v1/channels/{id} que o definiu ou alterou. Todas as outras respostas
dessas duas chamadas (só eventos alterados, webhook removido, uma reconexão que mantém
o segredo existente) trazem webhook_secret: null. GET /api/v1/channels e
GET /api/v1/channels/{id} nunca o retornam; eles apenas informam
has_webhook_secret: true | false. Guarde o valor quando ele for exibido — se
você o perder, a única opção é definir um novo.
Rotacionando. Defina um novo segredo a qualquer momento fornecendo um novo
webhook_secret ao PATCH /api/v1/channels/{id}, ou com as ações Generate random /
Save do Portal. Atualizar apenas webhook_url/webhook_events mantém o segredo
intacto. A mudança tem efeito na próxima entrega — não há janela de sobreposição,
então troque seu verificador para o novo segredo no mesmo momento, ou as assinaturas não
vão corresponder.
Restrições e recomendações.
| Tarefa | Endpoint |
|---|---|
| Listar todos os canais (ativos e inativos), cada um com seu estado de assinatura atual | GET /api/v1/channels |
| Inspecionar um canal | GET /api/v1/channels/{id} |
| Atualizar webhook URL / secret / events, ou o vínculo de assinatura | PATCH /api/v1/channels/{id} |
| Desativar um canal | DELETE /api/v1/channels/{id} |
Cada canal traz um bloco subscription descrevendo seu estado de cobrança — veja
Assinaturas e Cobrança para o que as
combinações significam. As listas completas de campos estão na Referência da API.
A desativação é um soft delete. O DELETE impede o canal de enviar e
receber, mas não o apaga — seu channel_id e histórico são preservados para que
você possa reconectar depois. O canal também continua pertencendo à mesma conta
Fiwano: a desativação não libera seu número do WhatsApp, conta do Instagram ou
Página do Facebook para conexão com outra conta Fiwano. Se o canal precisar ser
movido entre contas, entre em contato com support@fiwano.com.
Cada assinatura concede um slot por tipo de canal — um WhatsApp, um Instagram, um Facebook. Um slot permanece ocupado enquanto um canal estiver vinculado a ele, inclusive um canal desativado: é esse vínculo que permite reconectar aquele canal depois sem comprar outra assinatura.
GET /api/v1/subscriptions mostra qual canal ocupa cada slot e quantos estão
livres; cada canal, por sua vez, informa seu próprio subscription.id.
Envie subscription_id em PATCH /api/v1/channels/{channel_id} para mudar isso.
Um ID de assinatura move o canal para lá — sem indisponibilidade, e ele não
precisa ser desativado antes, mas mover para uma assinatura Starter interrompe o
envio de mídia e de templates imediatamente. Uma string vazia libera o slot, e
isso só é permitido para um canal já desativado com
DELETE /api/v1/channels/{channel_id}, de modo que um slot nunca é liberado como
efeito colateral de uma atualização de configuração.
Liberar um slot é, na prática, permanente. Assim que outro canal ocupar o slot liberado, o canal liberado não poderá mais ser reconectado até que haja um slot livre novamente. Ele não é apagado e sua identidade Meta continua pertencendo à sua conta Fiwano — mas trate a liberação como aposentar aquele canal, não como pausá-lo.
Substituindo um canal quando você tem apenas uma assinatura:
GET /api/v1/subscriptions → encontre a assinatura e seu slot ocupado
DELETE /api/v1/channels/{old_id} → desative o canal que será substituído
PATCH /api/v1/channels/{old_id} → {"subscription_id": ""} libera o slot
POST /api/v1/channels/setup-url → usuário conecta a nova conta Meta
POST /api/v1/channels/exchange-code → novo canal ocupa o slot livre
Um canal pode continuar ativo e mesmo assim não conseguir funcionar, quando a Meta
deixa de permitir que a Fiwano trabalhe com a conta ou o número: o app foi removido
nas configurações do Meta Business, uma permissão obrigatória foi revogada, a Página
ou a conta do WhatsApp ficou indisponível, o número de WhatsApp não está na WhatsApp
Business Platform (a conexão pelo WhatsApp Business App não foi concluída), a
Meta bloqueou a conta ou a Meta baniu o número de WhatsApp. A Fiwano então marca o canal como Action required no
portal e envia um e-mail ao dono da conta; o aviso e o e-mail dizem o que fazer.
Até a causa ser resolvida, os envios podem falhar — por exemplo com o erro 190.
Todo canal na API traz o mesmo estado em health:
"health": {
"status": "action_required",
"reason": "(#190) Error validating access token: …",
"since": "2026-10-06T10:00:00Z"
}
status é ok ou action_required — decida com base nele. reason é um texto
legível, normalmente o próprio erro da Meta com o código, que você pode pesquisar
na documentação da Meta; não decida com base nele. since é quando o problema foi
detectado. health volta a ok sozinho quando a Meta volta a permitir o acesso, e
na reconexão. is_active continua true: só vira false quando o canal é
desativado. Falhas de mensagens individuais não fazem parte de health — elas
chegam na resposta do envio e no webhook message.failed, e aparecem na página
Delivery problems do canal no portal.
Reconecte um canal desativado, ou marcado como Action required, executando o mesmo fluxo de conexão novamente para a mesma conta Meta (mesmo número de WhatsApp, conta do Instagram ou Página do Facebook). Quando a Meta bloqueou a conta ou baniu o número, resolva primeiro na Meta — só reconectar não remove o bloqueio:
channel_id, webhook
URL/secret/events e histórico são preservados. Nenhum canal novo é criado e o seu
mapeamento de channel_id armazenado continua válido.setup-url é recusado (402 ou
409, veja acima) — vincule uma assinatura primeiro, na página Billing do portal
ou via PATCH /api/v1/channels/{channel_id}.error=slot_occupied e nada é criado. Reconecte a mesma conta ou libere o slot
antes.support@fiwano.com para solicitar a liberação da titularidade.