Criar uma sessão de cadastro de número
Cria o link de uma página hospedada pela Synergy em que o SEU cliente conecta o WhatsApp dele (Embedded Signup da Meta) à sua organização. Redirecione (ou abra num pop-up, com return: "popup") o navegador do cliente para url.
Ao terminar, o cliente volta para redirect_url com session_id, state, status (e error, se houver) na query. O resultado AUTORITATIVO é o webhook synergy_onboarding ou GET /v1/onboarding-sessions/{session_id}: compare o state antes de liberar qualquer coisa.
Exige: plano pago com api (fora do teste grátis), conta em dia, o cadastro liberado pela plataforma para a organização, e redirect_url igual a uma URL de retorno cadastrada com o domínio provado. Sem vaga de número no plano a sessão nasce blocked (201) e nada é gasto.
Requer#
- Escopo da chave
- onboarding
onboardingComo os escopos funcionam - Recurso do plano
- API e webhooks
apiVer os planos que incluem - Formato
- Rota do Synergy. Erros no formato da Meta.
Parâmetros#
Cabeçalhos#
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| Authorization | string | obrigatório | Sua chave de API, no formato Bearer <chave>. Veja Autenticação. |
Corpo#
Tipo de conteúdo: application/json.
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| redirect_url | string | obrigatório | Para onde o cliente volta. Precisa ser IGUAL a uma URL de retorno cadastrada e com o domínio provado em Configurações → Desenvolvedor. |
| state | string | obrigatório | Seu anti-CSRF: opaco, devolvido sem alteração no redirect, no webhook e no GET da sessão. |
| mode | string | opcional | cloud: número novo na API oficial; coexistence: número que já usa o app WhatsApp Business; choice: o cliente escolhe na página. Valores: cloud, coexistence, choice. |
| return | string | opcional | popup: a página avisa a sua janela por postMessage e fecha. Valores: redirect, popup. |
| display_name | string | obrigatório | O nome da SUA plataforma, mostrado ao cliente. Caracteres invisíveis e de controle são removidos; nomes com Synergy, Meta, WhatsApp, Facebook, Instagram, "oficial" ou "verificado" são recusados. |
| external_ref | string | opcional | Seu id do cliente, devolvido no webhook. |
| attach_to_key_ids | string[] | opcional | Chaves restritas que recebem o número novo ao concluir (nunca uma chave de assistente). A chave que cria a sessão, se restrita, recebe sempre. |
| expires_in | integer | opcional | Validade do link, em segundos. |
Respostas#
| Status | Código | Quando acontece |
|---|---|---|
| 201 | — | Link pronto |
| 201 | — | Sem vaga de número no plano |
| 400 | — | Corpo inválido |
| 401 | — | Chave revogada ou desconhecida |
| 401 | 190 | Chave malformada ou forjada |
| 403 | — | A chave não tem o escopo onboarding |
| 403 | — | O plano da organização não inclui a API |
| 403 | — | Cadastro hospedado ainda não liberado para a organização |
| 403 | — | Cadastro hospedado suspenso pela plataforma |
| 403 | — | Conta em teste grátis |
| 403 | — | attach_to_key_ids com chave revogada, de outra organização ou de assistente |
| 413 | — | Corpo grande demais |
| 422 | — | URL não cadastrada |
| 422 | — | Domínio não provado |
| 429 | — | Limite de taxa |
| 429 | — | Cota de cadastros da organização em 7 dias |
| 429 | — | Limite semanal da plataforma na Meta |
| 429 | — | Mais de 50 sessões abertas |
Os erros no formato da Meta trazem o código em error.code. Ver todos os erros.
Corpo da resposta 201#
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| id | string | obrigatório | |
| status | string | obrigatório | Valores: pending, opened, completed, expired, cancelled, blocked. |
| url | string | null | obrigatório | O link para o cliente abrir: só enquanto pending. Uso único, preso ao primeiro navegador que o abre. |
| mode | string | obrigatório | Valores: cloud, coexistence, choice. |
| return | string | obrigatório | Valores: redirect, popup. |
| redirect_url | string | obrigatório | |
| state | string | obrigatório | |
| external_ref | string | null | obrigatório | |
| display_name | string | obrigatório | |
| created_at | string | obrigatório | |
| expires_at | string | obrigatório | |
| blocked | object | null | obrigatório | |
| last_error | object | null | obrigatório | |
| result | object | null | obrigatório |
Limites de taxa#
- Organização: 120 requisições a cada 60 s por chave (API_ORG_LIMIT).
Notas#
- As rotas da organização respondem no formato da gestão (
{ "error": … }, comreasonoufeaturequando há), não no da Graph API — exceto a chave malformada (401, código 190). - Uma chave recusada (revogada, ou sem o escopo) recebe este 401 pelos 60 s seguintes, por instância do Worker (cache de recusa, como na gestão).
curl
curl -X POST 'https://api.synergyconnect.com.br/v1/onboarding-sessions' \
-H "Authorization: Bearer $SYNERGY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"redirect_url":"https://app.minha-plataforma.com/whatsapp/ok","state":"e7f2c0d4-9b1e-4c52-8d0a-3f6a1b2c4d5e","mode":"choice","return":"redirect","display_name":"Minha Plataforma","external_ref":"tenant_8841","attach_to_key_ids":["0b9c4d1e-52a7-4f6b-8c3d-1e2f3a4b5c6d"],"expires_in":900}'JavaScript
const res = await fetch('https://api.synergyconnect.com.br/v1/onboarding-sessions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SYNERGY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"redirect_url": "https://app.minha-plataforma.com/whatsapp/ok",
"state": "e7f2c0d4-9b1e-4c52-8d0a-3f6a1b2c4d5e",
"mode": "choice",
"return": "redirect",
"display_name": "Minha Plataforma",
"external_ref": "tenant_8841",
"attach_to_key_ids": [
"0b9c4d1e-52a7-4f6b-8c3d-1e2f3a4b5c6d"
],
"expires_in": 900
}),
});
console.log(res.status, await res.json());Python
import os
import requests
res = requests.post(
"https://api.synergyconnect.com.br/v1/onboarding-sessions",
headers={
"Authorization": f"Bearer {os.environ['SYNERGY_API_KEY']}",
},
json={
"redirect_url": "https://app.minha-plataforma.com/whatsapp/ok",
"state": "e7f2c0d4-9b1e-4c52-8d0a-3f6a1b2c4d5e",
"mode": "choice",
"return": "redirect",
"display_name": "Minha Plataforma",
"external_ref": "tenant_8841",
"attach_to_key_ids": [
"0b9c4d1e-52a7-4f6b-8c3d-1e2f3a4b5c6d",
],
"expires_in": 900,
},
)
print(res.status_code, res.json())201
{
"id": "obs_4Fq9Lm2Xr7Tz1Vb8Nc3Kd6Hs",
"status": "pending",
"url": "https://app.synergyconnect.com.br/connect#obl_org_7Hk2pQ9_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA_bbbbbbbbbb",
"mode": "choice",
"return": "redirect",
"redirect_url": "https://app.minha-plataforma.com/whatsapp/ok",
"state": "e7f2c0d4-9b1e-4c52-8d0a-3f6a1b2c4d5e",
"external_ref": "tenant_8841",
"display_name": "Minha Plataforma",
"created_at": "2026-01-01T00:00:00.000Z",
"expires_at": "2026-01-01T00:15:00.000Z",
"blocked": null,
"last_error": null,
"result": null
}Há 2 casos com este status; veja a tabela de respostas.
400
{
"error": "Invalid body",
"issues": [
{
"code": "custom",
"path": [
"display_name"
],
"message": "reserved"
}
]
}401
{
"error": "Invalid or revoked key"
}Há 2 casos com este status; veja a tabela de respostas.
403
{
"error": "This key lacks the onboarding scope"
}Há 6 casos com este status; veja a tabela de respostas.
413
{
"error": "The body is too large (8 KB max)"
}422
{
"error": "Cadastre esta URL de retorno em Configurações → Desenvolvedor.",
"reason": "return_url_not_registered"
}Há 2 casos com este status; veja a tabela de respostas.
429
{
"error": "Rate limit hit"
}Há 4 casos com este status; veja a tabela de respostas.
Ficou com dúvida? Escreva para suporte@synergyconnect.com.br.