CRPRO HubEntrar no painel

Canais

GET
/api/v1/channels

Lista os canais da organização

Devolve os canais ativos da organização, mais recentes primeiro. Canais arquivados não aparecem aqui nem em nenhuma outra rota de canal — depois do DELETE, o id passa a responder 404 em todo o resto da API.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:read
Limite
120 requisições por minuto por organização e credencial
Requisição
curl https://crprohub.com/api/v1/channels \
  -H "Authorization: Bearer hub_pk_EXEMPLO_NAO_REAL"
Resposta
{
  "data": {
    "channels": [
      {
        "id": "9f6a9c1e-2f3d-4a5b-8c7d-1e2f3a4b5c6d",
        "name": "Atendimento",
        "external_id": null,
        "type": "whatsapp",
        "status": "active",
        "waba_id": "109876543210987",
        "phone_number_id": "123456789012345",
        "display_phone_number": "+55 21 99999-9999",
        "verified_name": "Minha Empresa",
        "quality_rating": "GREEN",
        "coexistence": false,
        "subscribed_ok": true,
        "created_at": "2026-08-01T12:00:00.000Z",
        "updated_at": "2026-08-20T09:30:00.000Z"
      }
    ]
  }
}
POST
/api/v1/channels

Cria um canal e emite o token do canal uma única vez

O canal nasce em draft, sem WABA nem número — a conexão com a Meta acontece depois, pelo link de /connect-link. O channel_token (hub_ch_...) vem só nesta resposta: não é reemitido, e perdê-lo obriga a rotacionar com /regenerate-token. Responde 402 se a assinatura não permite criar canais e 403 se o limite de canais do plano já foi atingido.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
120 requisições por minuto por organização e credencial

Corpo

ParâmetroTipoObrigatórioDescrição
namestringSimNome do canal, de 1 a 100 caracteres.
typeenumNãoSó aceita "whatsapp". Pode ser omitido.
external_idstringNãoIdentificador externo opcional, até 200 caracteres. Precisa ser único entre os canais ATIVOS da organização; duplicado responde 409 EXTERNAL_ID_CONFLICT. Excluir o canal libera o valor — dá para reconectar depois com o mesmo external_id.
Requisição
curl -X POST https://crprohub.com/api/v1/channels \
  -H "Authorization: Bearer hub_pk_EXEMPLO_NAO_REAL" \
  -H "Content-Type: application/json" \
  -d '{"name":"Atendimento"}'
Resposta
{
  "data": {
    "channel": {
      "id": "9f6a9c1e-2f3d-4a5b-8c7d-1e2f3a4b5c6d",
      "name": "Atendimento",
      "external_id": null,
      "type": "whatsapp",
      "status": "draft",
      "waba_id": null,
      "phone_number_id": null,
      "display_phone_number": null,
      "verified_name": null,
      "quality_rating": null,
      "coexistence": false,
      "subscribed_ok": false,
      "created_at": "2026-08-21T12:00:00.000Z",
      "updated_at": "2026-08-21T12:00:00.000Z"
    },
    "channel_token": "hub_ch_EXEMPLO_NAO_REAL"
  }
}
GET
/api/v1/channels/{id}

Consulta um canal

Um id de outro canal, de outra organização ou de um canal já arquivado responde 404 — não 403.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:read
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.
Requisição
curl https://crprohub.com/api/v1/channels/CHANNEL_UUID \
  -H "Authorization: Bearer hub_pk_EXEMPLO_NAO_REAL"
Resposta
{
  "data": {
    "channel": {
      "id": "9f6a9c1e-2f3d-4a5b-8c7d-1e2f3a4b5c6d",
      "name": "Atendimento",
      "external_id": null,
      "type": "whatsapp",
      "status": "active",
      "waba_id": "109876543210987",
      "phone_number_id": "123456789012345",
      "display_phone_number": "+55 21 99999-9999",
      "verified_name": "Minha Empresa",
      "quality_rating": "GREEN",
      "coexistence": false,
      "subscribed_ok": true,
      "created_at": "2026-08-01T12:00:00.000Z",
      "updated_at": "2026-08-20T09:30:00.000Z"
    }
  }
}
PATCH
/api/v1/channels/{id}

Atualiza o nome e as configurações do canal

É preciso enviar name ou external_id — corpo vazio ({}) responde 400. Campos omitidos ficam como estavam; enviar external_id: null remove o valor atual.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.

Corpo

ParâmetroTipoObrigatórioDescrição
namestringNãoNovo nome, de 1 a 100 caracteres.
external_idstringNãoNovo identificador externo, até 200 caracteres, ou null para remover o atual.
Requisição
curl -X PATCH https://crprohub.com/api/v1/channels/CHANNEL_UUID \
  -H "Authorization: Bearer hub_pk_EXEMPLO_NAO_REAL" \
  -H "Content-Type: application/json" \
  -d '{"name":"Atendimento — Loja 2"}'
Resposta
{
  "data": {
    "channel": {
      "id": "9f6a9c1e-2f3d-4a5b-8c7d-1e2f3a4b5c6d",
      "name": "Atendimento — Loja 2",
      "external_id": null,
      "type": "whatsapp",
      "status": "active",
      "waba_id": "109876543210987",
      "phone_number_id": "123456789012345",
      "display_phone_number": "+55 21 99999-9999",
      "verified_name": "Minha Empresa",
      "quality_rating": "GREEN",
      "coexistence": false,
      "subscribed_ok": true,
      "created_at": "2026-08-01T12:00:00.000Z",
      "updated_at": "2026-08-21T12:05:00.000Z"
    }
  }
}
DELETE
/api/v1/channels/{id}

Arquiva o canal e, opcionalmente, tira o número da Meta

É um soft delete: o registro continua no banco, mas some de toda a API (GET, mensagens, mídia, templates passam a responder 404 para este id). Não há endpoint para desarquivar — é preciso criar um canal novo. A vaga do plano é liberada na hora. Em toda exclusão o Hub também revoga o token do canal, invalida links de conexão pendentes, desvincula o canal dos endpoints de webhook e apaga o token da Meta guardado para ele — isso acontece mesmo se o deregister falhar. Com deregister=true, antes de arquivar o Hub ainda chama o deregister do número na Cloud API: a chamada age só naquele número e não mexe no app da WABA, então os outros números da mesma conta continuam funcionando. Depois do deregister o cliente precisa registrar o número de novo, com o PIN da verificação em duas etapas. Se a Meta recusar (token expirado, número já desregistrado), a exclusão acontece do mesmo jeito e a falha fica gravada no log de auditoria como channel.deregister_failed. O mesmo vale quando a credencial da Meta do canal nao pode ser lida (deregistro: sem-credencial) — o número segue registrado na Meta e precisa ser resolvido no Business Manager.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.

Parâmetros de consulta

ParâmetroTipoObrigatórioDescrição
deregisterbooleanNãoUse true para também tirar o número da Cloud API da Meta antes de arquivar. Omitido, o canal só é arquivado no Hub e o número continua registrado na Meta.
Requisição
curl -X DELETE "https://crprohub.com/api/v1/channels/CHANNEL_UUID?deregister=true" \
  -H "Authorization: Bearer hub_pk_EXEMPLO_NAO_REAL"
Resposta
{
  "data": {
    "archived": true,
    "changed": true,
    "deregistro": "feito"
  }
}
POST
/api/v1/channels/{id}/connect-link

Gera um link de conexão para o cliente final

O link expira em 7 dias e serve para o cliente final autorizar o número dele direto na Meta, sem precisar de credencial do painel. Cada chamada gera um connect_token novo e invalida qualquer link anterior ainda não usado — não há como recuperar um link já gerado, só criar outro.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.
Requisição
curl -X POST https://crprohub.com/api/v1/channels/CHANNEL_UUID/connect-link \
  -H "Authorization: Bearer hub_pk_EXEMPLO_NAO_REAL"
Resposta
{
  "data": {
    "connect_token": "hub_link_EXEMPLO_NAO_REAL",
    "expires_at": "2026-08-28T12:00:00.000Z",
    "connect_url": "https://crprohub.com/connect/hub_link_EXEMPLO_NAO_REAL"
  }
}
GET
/api/v1/channels/{id}/diagnostics

Valida token, número e assinatura de webhooks sem expor segredos

Faz três checagens ao vivo na Meta (validade do token, número acessível, app inscrito na WABA) e nunca devolve o token em si, só checks booleanos e recommendations. Exige que o canal já esteja conectado (com waba_id e phone_number_id); senão responde 409 CHANNEL_NOT_CONNECTED. O token hub_ch_... do próprio canal também autentica esta chamada, mas nunca autoriza consultar outro canal.

Autenticação
Sessão do painel, Chave de API, Token do canal
Escopo
channels:read
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.
Requisição
curl https://crprohub.com/api/v1/channels/CHANNEL_UUID/diagnostics \
  -H "Authorization: Bearer hub_ch_EXEMPLO_NAO_REAL"
Resposta
{
  "data": {
    "diagnostics": {
      "overall": "healthy",
      "checked_at": "2026-08-21T12:10:00.000Z",
      "checks": {
        "token_valid": true,
        "phone_accessible": true,
        "app_subscribed": true
      },
      "channel": {
        "id": "9f6a9c1e-2f3d-4a5b-8c7d-1e2f3a4b5c6d",
        "phone_number_id": "123456789012345",
        "waba_id": "109876543210987",
        "quality_rating": "GREEN",
        "status": "CONNECTED",
        "verified_name": "Minha Empresa"
      },
      "recommendations": []
    }
  }
}
POST
/api/v1/channels/{id}/deregister

Tira o número da plataforma da Meta sem excluir o canal

Chama o deregister do número na Meta e rebaixa o canal para connected — vinculado, mas sem poder enviar. Diferente de DELETE ?deregister=true, o canal NÃO é arquivado: o token continua válido, os links seguem de pé e a vaga do plano não é liberada. Serve para tirar um número da API Local (On-Premises) e reconectá-lo em seguida com o PIN da verificação em duas etapas. Enquanto o número não for registrado de novo, os envios respondem 409 CHANNEL_NOT_CONNECTED — isso é esperado, porque o número realmente não envia. O status HTTP desta rota é sempre 200, para os quatro valores possíveis do campo deregistro — 200 NÃO significa que o número foi liberado da Meta; quem chama precisa olhar o campo deregistro, nunca só o status, para saber o que de fato aconteceu. Os quatro valores: "feito" — a Meta aceitou o deregister e o canal foi rebaixado para connected; "falhou" — a Meta recusou (token expirado, número já desregistrado, cota estourada etc.), nada mudou no canal, e o motivo da recusa vem no campo motivo e no log de auditoria como channel.deregister_failed; "sem-numero" — o canal não tem phone_number_id vinculado, não havia o que desregistrar; "sem-credencial" — a credencial da Meta deste canal não pôde ser lida, o número segue registrado e precisa ser resolvido no Business Manager. Depois de um "falhou", não fique retentando sem investigar o motivo: a Meta limita o register a 10 chamadas por número em janela móvel de 72h, e o deregister a outras 10, contadas à parte (erro #133016); cada tentativa — inclusive as que falham — consome uma dessas chamadas.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.
Requisição
curl -X POST "https://crprohub.com/api/v1/channels/CHANNEL_UUID/deregister" \
  -H "Authorization: Bearer hub_sk_EXEMPLO_NAO_REAL"
Resposta
{
  "data": {
    "deregistro": "feito",
    "changed": true,
    "motivo": null
  }
}
POST
/api/v1/channels/{id}/register

Conclui o registro do número na Cloud API com o PIN

Para canais no status connected — número vinculado, recebendo mensagens, mas sem poder enviar porque o registro na Cloud API ficou pendente. O Hub chama o /register da Meta com a credencial que ele guarda para o canal e, se der certo, promove o canal para active e emite channel.connected, exatamente como o fluxo do link de conexão. É idempotente: se o canal já está active, ou se a Meta já reporta o número como registrado na Cloud API, a resposta é 200 com already_registered: true, sem nova chamada de register. Qualquer outro status responde 409 NOT_PENDING_REGISTRATION. O PIN precisa ser uma string de exatamente 6 dígitos (senão 422 INVALID_PIN_FORMAT, sem ir à Meta). Ele não é gravado nem aparece em log, auditoria ou resposta. Erros com código próprio: 400 INVALID_PIN (o PIN não confere; details.attempts_remaining), 400 PIN_REQUIRED_RECOVERY (terceiro PIN recusado na janela de 1 hora — a verificação em duas etapas já está ativa com outro PIN, e só a redefinição no WhatsApp Manager ou o link de conexão resolvem), 429 PIN_LOCKED (details.locked_by = hub quando o limite deste endpoint estourou, com retry_after_seconds e header Retry-After; = meta quando a Meta bloqueou, com retry_after_seconds null — a Meta informa o prazo no detalhe do erro, que o Hub ainda não repassa — e retry_window_hours: 72 no erro #133016), 502 META_AUTH_FAILED (credencial da Meta inválida, expirada ou ausente), 502/504 META_UNREACHABLE (Meta instável ou sem resposta) e 422 REGISTRATION_REJECTED (outra recusa da Meta; details.meta_code traz o código, e details.reason = on_premises quando o número está na API Local). Este endpoint é o atalho para quem sabe o PIN. Quem esqueceu o PIN continua precisando do link de conexão ou da recuperação da Meta. A Meta limita register e deregister a 10 chamadas por número em 72h.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
5 por hora por canal

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.

Corpo

ParâmetroTipoObrigatórioDescrição
pinstringSimPIN da verificação em duas etapas do número: exatamente 6 dígitos, como string.
Requisição
curl -X POST "https://crprohub.com/api/v1/channels/CHANNEL_UUID/register" \
  -H "Authorization: Bearer hub_sk_EXEMPLO_NAO_REAL" \
  -H "Content-Type: application/json" \
  -d '{"pin":"000000"}'
Resposta
{
  "data": {
    "status": "active",
    "phone_number_id": "123456789012345",
    "already_registered": false
  }
}
POST
/api/v1/channels/{id}/credentials

Conecta o canal com as credenciais do app da Meta do próprio cliente

Alternativa ao link de conexão para quem já tem um app na Meta, um usuário do sistema com token permanente e o número nesse app. Antes de gravar, o Hub confere o App Secret, confere o token (válido, do mesmo app, com whatsapp_business_management e whatsapp_business_messaging sobre a WABA), confere que o número pertence à WABA e assina o app nos webhooks da WABA. Em seguida aponta os webhooks do número para a URL do app no Hub (webhook.callback_url). Se esse passo falhar, a conexão continua e webhook_override vem false: nesse caso, configure a URL e o verify token devolvidos como URL padrão do app, em WhatsApp > Configuração. Mesmo com o override, eventos de conta (status de template, qualidade do número, account_update) só chegam pela URL padrão do app. Número já registrado na Cloud API fica active. Número ainda não registrado fica connected (registration_pending: true); com pin no corpo, o Hub registra na sequência pelo mesmo fluxo de /register, e uma recusa do PIN não desfaz a conexão (o erro vem em registro). Serve também para trocar um token vencido ou migrar um canal do Embedded Signup para o app próprio. App Secret, token e PIN não são devolvidos nem registrados em log ou auditoria. Erros com código próprio: 400 INVALID_BODY (details.campos lista os campos fora do formato), 422 INVALID_PIN_FORMAT, 409 CHANNEL_SUSPENDED, 422 META_APP_SECRET_INVALID, 422 META_TOKEN_INVALID, 422 META_TOKEN_APP_MISMATCH, 422 META_TOKEN_SCOPE_MISSING, 422 PHONE_NUMBER_NOT_IN_WABA, 502 META_SUBSCRIPTION_FAILED, 502 META_UNREACHABLE e 409 PHONE_ALREADY_CONNECTED.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.

Corpo

ParâmetroTipoObrigatórioDescrição
phone_number_idstringSimPhone Number ID do número, só dígitos.
waba_idstringSimID da conta do WhatsApp Business (WABA), só dígitos.
app_idstringSimApp ID do app da Meta que gerou o token, só dígitos.
app_secretstringSimApp Secret desse app (hexadecimal). Usado para conferir a assinatura dos webhooks.
access_tokenstringSimToken do usuário do sistema, de preferência permanente.
pinstringNãoPIN da verificação em duas etapas (6 dígitos), para registrar o número se ele ainda não estiver na Cloud API.
Requisição
curl -X POST "https://crprohub.com/api/v1/channels/CHANNEL_UUID/credentials" \
  -H "Authorization: Bearer hub_sk_EXEMPLO_NAO_REAL" \
  -H "Content-Type: application/json" \
  -d '{"phone_number_id":"123456789012345","waba_id":"234567890123456","app_id":"345678901234567","app_secret":"0123456789abcdef0123456789abcdef","access_token":"EAAEXEMPLONAOREAL"}'
Resposta
{
  "data": {
    "channel": { "id": "CHANNEL_UUID", "status": "active", "meta_app_id": "345678901234567" },
    "registration_pending": false,
    "registro": null,
    "webhook_override": true,
    "webhook": {
      "callback_url": "https://crprohub.com/api/webhook/meta/apps/345678901234567",
      "verify_token": "EXEMPLO_NAO_REAL"
    },
    "warnings": []
  }
}
POST
/api/v1/channels/{id}/regenerate-token

Rotaciona o token do canal; o novo valor aparece uma única vez

O token anterior é revogado imediatamente: qualquer integração ainda usando o hub_ch_... antigo passa a responder 401 no mesmo instante. O novo valor só aparece nesta resposta — se você perdê-lo, o único jeito de recuperar é rotacionar de novo.

Autenticação
Sessão do painel, Chave de API
Escopo
channels:write
Limite
120 requisições por minuto por organização e credencial

Parâmetros de caminho

ParâmetroTipoObrigatórioDescrição
idUUIDSimIdentificador do canal.
Requisição
curl -X POST https://crprohub.com/api/v1/channels/CHANNEL_UUID/regenerate-token \
  -H "Authorization: Bearer hub_pk_EXEMPLO_NAO_REAL"
Resposta
{
  "data": {
    "channel_token": "hub_ch_EXEMPLO_NAO_REAL",
    "warning": "O token anterior foi revogado. Guarde este valor agora."
  }
}