Pular para o conteúdo principal

Phones (canais)

Phones representam cada conexão WhatsApp ou Instagram da sua account. São o pré-requisito para enviar/receber qualquer mensagem.

Base path: /v1/phones

Objeto Phone

{
"id": "5f7b2e1c-3d4a-4e5f-9a8b-1c2d3e4f5a6b",
"accountId": "a1b2c3d4-...",
"type": "BAILEYS",
"label": "Atendimento Vendas",
"phoneNumber": "5511999998888",
"status": "CONNECTED",
"webhookUrl": "https://api.minhaempresa.com/wpp-events",
"webhookEvents": ["message:received", "message:status"],
"createdAt": "2026-05-21T14:00:00.000Z",
"updatedAt": "2026-05-21T14:02:30.000Z"
}

Campos comuns

CampoTipoDescrição
idUUIDIdentificador local (use em todos os endpoints)
typeenumBAILEYS, WABA, INSTAGRAM (imutável)
labelstringNome legível (1-120 chars)
phoneNumberstring | nullE.164 sem +, populado após conexão
statusenumPENDING, PENDING_QR, PENDING_WEBHOOK, CONNECTING, CONNECTED, DISCONNECTED, TOKEN_EXPIRED, FAILED
webhookUrlstring | nullOnde o gateway entrega eventos
webhookEventsstring[]Lista de eventos subscritos (vazio = todos)
disconnectedAtdatetime | nullQuando saiu de CONNECTED

Campos exclusivos WABA

wabaPhoneNumberId, wabaBusinessAccountId, wabaThroughputLevel, wabaQualityRating, wabaWebhookConfigured. Tokens (wabaAccessTokenEnc) são internos — nunca retornados.

Campos exclusivos Instagram

igUserId, igUsername, igAccountType, igTokenExpiresAt, igWebhookConfigured.


Endpoints

POST /v1/phones

Cria um novo phone. Para BAILEYS, inicia geração do QR. Para WABA, valida as credenciais e hidrata metadata. Para INSTAGRAM, use o fluxo OAuth dedicado.

Headers

HeaderValorObrigatório
X-API-Keyak_live_...sim
Content-Typeapplication/jsonsim

Body

CampoTipoObrigatórioDescrição
typeenumsimBAILEYS ou WABA (Instagram usa endpoint próprio)
labelstringsim1-120 chars
webhook.urlURLnãoEndpoint HTTPS pra eventos
webhook.secretstringnãoSecret HMAC (≥16 chars; obrigatório se url presente)
webhook.eventsstring[]nãoLista de tipos (vazio = todos)
credentials.phoneNumberIdstringsó WABAPhone Number ID do Meta
credentials.businessAccountIdstringsó WABAWABA ID
credentials.accessTokenstringsó WABASystem User token longo
credentials.verifyTokenstringsó WABAToken de verificação webhook

Exemplo Baileys:

curl -X POST https://wpp.ogmma.com.br/v1/phones \
-H "X-API-Key: ak_live_..." \
-H "Content-Type: application/json" \
-d '{
"type": "BAILEYS",
"label": "Atendimento Vendas",
"webhook": {
"url": "https://api.acme.com/wpp",
"secret": "supersecret-pelomenos-16chars",
"events": ["message:received", "channel:connected"]
}
}'

Exemplo WABA manual (credenciais via Meta Business Manager):

curl -X POST https://wpp.ogmma.com.br/v1/phones \
-H "X-API-Key: ak_live_..." \
-H "Content-Type: application/json" \
-d '{
"type": "WABA",
"label": "Comercial Oficial",
"credentials": {
"phoneNumberId": "123456789012345",
"businessAccountId": "987654321098765",
"accessToken": "EAAxxx...",
"verifyToken": "meu-verify-token"
},
"webhook": { "url": "https://api.acme.com/wpp", "secret": "supersecret-pelomenos-16chars" }
}'

Response 201

{
"id": "5f7b2e1c-...",
"type": "BAILEYS",
"status": "PENDING_QR",
"label": "Atendimento Vendas",
"webhookUrl": "https://api.acme.com/wpp",
"createdAt": "2026-05-21T14:00:00.000Z"
}

Errors

HTTPCodeQuando
400VALIDATION_ERRORCampo inválido
400WABA_CREDENTIALS_REQUIREDtype=WABA sem credentials
401AUTH_MISSINGSem X-API-Key
402ACCOUNT_SUSPENDEDAccount em inadimplência

GET /v1/phones

Lista todos os phones da account, ordenados por createdAt desc.

curl https://wpp.ogmma.com.br/v1/phones \
-H "X-API-Key: ak_live_..."

Response 200

[
{ "id": "...", "type": "BAILEYS", "status": "CONNECTED", ... },
{ "id": "...", "type": "WABA", "status": "CONNECTED", ... }
]

GET /v1/phones/:id

Detalhe de um phone específico.

curl https://wpp.ogmma.com.br/v1/phones/5f7b2e1c-... \
-H "X-API-Key: ak_live_..."

Errors

HTTPCodeQuando
404PHONE_NOT_FOUNDID inexistente ou pertence a outra account

DELETE /v1/phones/:id

Remove um phone. Worker é notificado para encerrar a sessão (Baileys envia logout). Operação destrutiva e irreversível — auth state e mídia local são apagados; mensagens enviadas (messages_sent) ficam para auditoria.

curl -X DELETE https://wpp.ogmma.com.br/v1/phones/5f7b2e1c-... \
-H "X-API-Key: ak_live_..."

Response 204 (sem body)


PATCH /v1/phones/:id

Atualiza apenas a configuração de webhook do phone. Não permite trocar type ou label.

Body

CampoTipoDescrição
webhook.urlURL | nullnull ou omitido remove o webhook
webhook.secretstring≥16 chars
webhook.eventsstring[]Lista de tipos
sharedWebhookIdUUID | nullAponta para um SharedWebhook (futura feature multi-phone)
curl -X PATCH https://wpp.ogmma.com.br/v1/phones/5f7b2e1c-... \
-H "X-API-Key: ak_live_..." \
-H "Content-Type: application/json" \
-d '{ "webhook": { "url": "https://api.acme.com/wpp-v2", "secret": "novachavedepelomenos16chars" } }'

GET /v1/phones/:id/qrcode

Retorna o QR code Baileys atual (cacheado em Redis com TTL curto após o Worker gerar). Faça polling a cada 1-2s; quando o usuário escanear, o status vira CONNECTED e este endpoint passa a retornar 409.

Response 200

{
"qr": "2@LkPq...,QR data raw...",
"dataUrl": "data:image/png;base64,iVBORw0KGgo..."
}

dataUrl é PNG base64 pronto para <img src="...">.

Errors

HTTPCodeQuando
400QR_NOT_APPLICABLEPhone não é BAILEYS
404PHONE_NOT_FOUND
409ALREADY_CONNECTEDPhone já conectou
425QR_NOT_READYQR ainda não emitido pelo Worker — tente em 1-2s

O QR rota Baileys naturalmente refresha a cada ~20s. O endpoint sempre devolve o último QR em cache.


POST /v1/phones/:id/pairing-code

Alternativa ao QR para Baileys: gera um código de 8 dígitos que o usuário digita no celular em "Aparelhos conectados → Conectar com número".

Body

CampoTipoObrigatórioDescrição
phoneNumberstringsimE.164 (com ou sem +), 8-20 dígitos
curl -X POST https://wpp.ogmma.com.br/v1/phones/5f7b2e1c-.../pairing-code \
-H "X-API-Key: ak_live_..." \
-H "Content-Type: application/json" \
-d '{ "phoneNumber": "+5511988887777" }'

Response 202

{ "status": "pending", "phoneNumber": "5511988887777" }

A criação do código é assíncrona (Worker recebe o comando, cria a sessão Baileys com requestPairingCode, salva o resultado em Redis). Faça polling em GET /pairing-code.

Errors

HTTPCodeQuando
400PAIRING_NOT_APPLICABLEPhone não é BAILEYS
409ALREADY_CONNECTEDPhone já conectou

GET /v1/phones/:id/pairing-code

Busca o pairing code gerado no comando anterior. Faça polling até 200.

Response 200

{ "code": "ABCD1234", "formatted": "ABCD-1234" }

Errors

HTTPCodeQuando
425PAIRING_NOT_READYCódigo ainda sendo gerado pelo Worker — tente em 1-2s

O pairing code é único e descartável. Uma vez consumido (usuário digitou no celular), o Worker emite channel:pairing-code (uso interno) e depois channel:connected.


POST /v1/phones/:id/reconnect

Força o Worker a reabrir a sessão (útil quando o phone entrou em DISCONNECTED por instabilidade temporária). Para Baileys, tenta recuperar via auth state persistido. Para WABA, recarrega credenciais.

curl -X POST https://wpp.ogmma.com.br/v1/phones/5f7b2e1c-.../reconnect \
-H "X-API-Key: ak_live_..."

Response 202

{ "status": "reconnecting" }

GET /v1/phones/:id/identities/resolve

Resolve uma identidade do contato. Aceita qualquer formato: canonicalKey, phone (5511999...), BSUID (BR.1234...), username (@maria), ou JID Baileys (5511999@s.whatsapp.net, 123@lid).

Query

ParamTipoObrigatório
keystringsim
curl 'https://wpp.ogmma.com.br/v1/phones/5f7b2e1c-.../identities/resolve?key=5511988887777' \
-H "X-API-Key: ak_live_..."

Response 200

{
"canonicalKey": "+5511988887777",
"pn": "5511988887777",
"lid": null,
"bsuid": null,
"username": null,
"firstSeenAt": "2026-04-12T10:00:00.000Z",
"lastSeenAt": "2026-05-20T18:33:00.000Z"
}

Errors

HTTPCodeQuando
404IDENTITY_NOT_FOUNDChave não encontrada nesse phone

WABA Embedded Signup

Fluxo recomendado para WABA quando o cliente não tem credenciais Meta ainda. Usa o SDK JS da Meta no browser.

GET /v1/phones/waba/embedded-signup/config

Retorna config para o SDK Meta inicializar.

curl https://wpp.ogmma.com.br/v1/phones/waba/embedded-signup/config \
-H "X-API-Key: ak_live_..."

Response 200

{
"appId": "1234567890",
"configId": "9876543210",
"graphVersion": "v25.0"
}

Errors

HTTPCodeQuando
503META_APP_ID_MISSINGGateway sem META_APP_ID configurado

POST /v1/phones/waba/embedded-signup

Finaliza o signup após o usuário completar o fluxo no SDK Meta (recebe code + phone_number_id + waba_id do callback).

Body

CampoTipoObrigatórioDescrição
codestringsimAuthorization code retornado pelo SDK Meta
phoneNumberIdstringsimID do número selecionado
wabaIdstringsimID da WABA
labelstringnãoDefault: "WhatsApp Business"
pinstringnãoPIN 6 dígitos para register (default "000000" em dev)
webhookobjectnãoConfig webhook (mesma do POST /phones)
curl -X POST https://wpp.ogmma.com.br/v1/phones/waba/embedded-signup \
-H "X-API-Key: ak_live_..." \
-H "Content-Type: application/json" \
-d '{
"code": "AQDxYzAbCd...",
"phoneNumberId": "123456789012345",
"wabaId": "987654321098765",
"label": "WhatsApp Acme",
"pin": "123456"
}'

Response 201 — phone criado com status: CONNECTED.

O gateway executa:

  1. Trocar code por system user token (server-side, com META_APP_SECRET).
  2. subscribeAppToWaba para receber webhooks.
  3. Registrar o número (pode falhar silenciosamente se já registrado).
  4. Hidratar metadata via getPhoneNumberInfo.
  5. Persistir phone + disparar channel:connect no Worker.

Errors

HTTPCodeQuando
503META_APP_NOT_CONFIGUREDSem META_APP_ID/META_APP_SECRET no servidor

Instagram OAuth

GET /v1/phones/instagram/oauth/config

Retorna config para iniciar o fluxo OAuth Instagram.

Response 200

{
"appId": "...",
"redirectUri": "https://app.acme.com/oauth/instagram/callback",
"scope": "instagram_business_basic,instagram_business_manage_messages",
"authorizationUrl": "https://www.instagram.com/oauth/authorize?client_id=...&redirect_uri=..."
}

POST /v1/phones/instagram

Finaliza o OAuth com o code recebido no redirect.

Body

CampoTipoObrigatório
codestringsim
labelstringnão
webhookobjectnão
curl -X POST https://wpp.ogmma.com.br/v1/phones/instagram \
-H "X-API-Key: ak_live_..." \
-H "Content-Type: application/json" \
-d '{ "code": "AQDxYz...", "label": "Instagram Acme" }'

Response 201 — phone com type: INSTAGRAM, status: CONNECTED, token long-lived (60d) armazenado criptografado.

Errors

HTTPCodeQuando
503IG_NOT_CONFIGUREDServidor sem credenciais Instagram

WABA Business Profile

GET /v1/phones/:id/business-profile

Retorna o perfil público do número WABA (about, websites, vertical, etc) direto do Meta.

curl https://wpp.ogmma.com.br/v1/phones/5f7b2e1c-.../business-profile \
-H "X-API-Key: ak_live_..."

PATCH /v1/phones/:id/business-profile

Atualiza o perfil.

Body (todos opcionais)

CampoTipoLimite
aboutstring139 chars
addressstring256 chars
descriptionstring512 chars
emailemail
websitesURL[]até 2
verticalenumAUTO, BEAUTY, RETAIL, RESTAURANT, etc.

Response 204


WABA Phone Number lifecycle

Endpoints administrativos do número (alternativa ao Embedded Signup quando o cliente quer controle granular).

POST /v1/phones/:id/request-code

Solicita código de verificação SMS ou voz.

Body

CampoTipoDefault
methodSMS | VOICESMS
localestringpt_BR

Response 204

POST /v1/phones/:id/verify-code

Confirma o código recebido por SMS/voz.

Body: { "code": "123456" }Response 204

POST /v1/phones/:id/register

Registra o número na WABA (passo final). PIN obrigatório.

Body: { "pin": "123456" }Response 204

POST /v1/phones/:id/deregister

Desregistra o número (libera para outra WABA).

Response 204

POST /v1/phones/:id/request-name-change

Solicita mudança de display name (precisa aprovação Meta).

Body: { "name": "Acme Atendimento" }Response 200 com request_id.

POST /v1/phones/:id/two-step-pin

Define o PIN de 6 dígitos (2-step verification).

Body: { "pin": "123456" }Response 204

POST /v1/phones/:id/rotate-token

Substitui o access token armazenado (sem precisar re-onboardar). Útil quando o System User Token é rotacionado no Business Manager.

Body: { "accessToken": "EAAxxx..." }Response 204

Validação: o gateway chama getPhoneNumberInfo com o novo token antes de salvar.


WABA Block/Unblock

GET /v1/phones/:id/blocked

Lista usuários bloqueados pelo número (anti-spam).

Response 200

{ "users": [{ "input": "5511988887777", "wa_id": "5511988887777", ... }] }

POST /v1/phones/:id/block

Body: { "users": ["5511988887777", ...] } (1-100 itens) → Response 204

POST /v1/phones/:id/unblock

Mesmo formato. Response 204


WhatsApp Business Account (WABA-level)

Endpoints para inspeção da WABA inteira (não do número individual).

GET /v1/phones/:id/waba

Retorna info da WABA.

GET /v1/phones/:id/waba/phones

Lista todos os números registrados naquela WABA.

GET /v1/phones/:id/waba/subscribed-apps

Lista apps Meta com webhook subscrito.

POST /v1/phones/:id/waba/subscribed-apps

Re-subscreve o app gateway aos webhooks.

Body (opcional)

CampoTipo
overrideCallbackUriURL
verifyTokenstring

Response 204

DELETE /v1/phones/:id/waba/subscribed-apps

Remove subscription. Response 204