Skip to main content
Use este fluxo quando sua aplicação precisa conectar um número da API oficial do WhatsApp à organização Spark sem que a pessoa passe pelo painel do CRM. O Spark hospeda a etapa com a Meta; sua integração só cria a sessão, abre a URL para o usuário final e reage ao resultado. Para conectar manualmente pelo dashboard, veja Conectar WhatsApp Business (API oficial). Para autenticação, chaves e base URL, veja Introdução à API.

Pré-requisitos

Base URL: gateway.crmspark.com.br (prefixo /v1).

O que acontece, em resumo

  1. Seu backend chama POST /v1/entrypoints/whatsapp/connection-sessions e recebe sessionId, url e expiresAt.
  2. Você direciona a pessoa para url (página do Spark). Ela faz login na Meta e autoriza o número.
  3. O Spark finaliza a conexão e cria o entrypoint (canal WhatsApp oficial) na organização.
  4. Você descobre o resultado por webhook (entrypoints.whatsapp.connected ou entrypoints.whatsapp.connection_failed) ou por polling em GET …/connection-sessions/{sessionId}.
A API não devolve códigos OAuth da Meta nem tokens de longa duração para sua aplicação. Credenciais e vínculo do número ficam no Spark; você recebe o entrypoint criado (id, phoneNumberId, wabaId, etc.) quando a conexão conclui.

Endpoints

A referência OpenAPI ao lado documenta cada campo, exemplo e código de erro.

Criar uma sessão

Corpo (application/json): Resposta 202:

Como abrir a url

  • Abra em janela de topo ou nova aba (window.open com _blank ou redirecionamento). A resposta 202 da API descreve explicitamente “janela de topo” — popups bloqueados ou iframes costumam quebrar o fluxo da Meta.
  • Guarde sessionId no seu backend antes de enviar o usuário à url.
  • A url é de uso único e sensível: trate como link de convite (não logue em analytics públicos, não compartilhe em canais inseguros).

Consultar a sessão

GET /v1/entrypoints/whatsapp/connection-sessions/{sessionId} com a mesma chave sk_. Status possíveis: Enquanto pending, entrypoint é null. Em completed, você recebe, entre outros:
  • entrypoint.id — use em envios e listagens (GET /v1/entrypoints, mensageria, etc.).
  • phoneNumberId, wabaId, displayPhone, name
  • funnelId, funnelStepId, isCoexistence — espelham o que foi configurado na sessão.
Motivos de falha (reason): O campo message pode trazer texto legível para exibir ao usuário; para lógica no código, prefira status e reason.
Em produção, trate o webhook como fonte principal e use GET como fallback (tela de “aguardando conexão”, suporte ou reconciliação). Faça polling com intervalo razoável (ex.: 2–5 s) só enquanto pending, e pare ao receber evento final ou ao passar expiresAt.

Webhooks

Cadastre no portal Svix (aba Webhooks do painel) os eventos do grupo entrypoints: Formato geral, assinatura Svix, retentativas e idempotência: Webhooks. Exemplo enxuto de sucesso:

Fluxo recomendado para integradores

1

Criar sessão no servidor

Chame POST com sk_, opcionalmente funil e returnUrl. Persista sessionId associado ao usuário ou tenant da sua aplicação.
2

Abrir a URL para o usuário

Redirecione ou abra url em janela de topo. Mostre contagem regressiva até expiresAt se quiser melhorar a UX.
3

Aguardar o resultado

No handler de webhook, filtre por sessionId. Atualize seu banco com entrypoint.id em connected. Em connection_failed, informe o usuário e ofereça criar nova sessão.
4

Usar o canal conectado

Liste entrypoints (GET /v1/entrypoints?platform=whatsapp) ou use o id do webhook para enviar mensagens pela API de mensageria e automações já documentadas.

SDK TypeScript

Com o pacote sparkcrm:
Tipos de webhook: EntrypointsWhatsappConnectedWebhook e EntrypointsWhatsappConnectionFailedWebhook em TypeScript — webhooks e tipos.

Limitações e boas práticas

  • Uma sessão, um fluxo: cada POST gera nova url e novo prazo. Se expirar ou falhar, crie outra sessão; não reutilize url antiga.
  • Prazo fixo de 20 minutos: após expiresAt, o status passa a expired (webhook connection_failed com reason: expired).
  • Somente API oficial: este fluxo não substitui WhatsApp Lite (QR code); use os entrypoints whatsapp_lite pelo painel ou outras APIs conforme a referência.
  • Funil opcional: sem funnelStepId, o número conecta sem etapa padrão; você pode ajustar depois no painel em Canais.
  • Coexistência: só marque coexistence: true quando o caso de uso exigir o modo coexistência com o app Business; o fluxo na página do Spark difere do Embedded Signup padrão.
  • Rate limit: respeite 429 (RATE_LIMIT_EXCEEDED) com backoff; evite polling agressivo em muitas sessões paralelas.
  • Segurança: nunca exponha sk_ no front-end. Crie a sessão sempre no backend; o front só recebe a url (ou um redirect controlado por você).

Erros comuns

Leitura adicional