Documentation Index

Fetch the complete documentation index at: https://help.hiplatform.com/llms.txt

Use this file to discover all available pages before exploring further.

Documentação Técnica da API Pública do Hi Broker v1

Prev Next

Sobre a função

O Hi Broker é o componente responsável por intermediar a comunicação entre a Hi Platform e a Meta (WhatsApp Business Platform). Ele processa disparos de mensagens, captura status de entrega e recebimento e encaminha eventos para os Webhooks configurados pelo cliente.

Com esse recurso, é possível acompanhar toda a jornada de mensagens enviadas e recebidas via WhatsApp, além de manter a rastreabilidade dos eventos e conteúdos trocados.

1. Visão Geral

A API pública do Hi Broker atua como camada de integração entre sistemas clientes e a WhatsApp Cloud API / Business Management API da Meta.

Em vez de cada integração gerenciar sua própria autenticação com a Meta, o Hi Broker centraliza:

  • A autorização do tenant autenticado.
  • O vínculo com a WhatsApp Business Account (WABA) e os números de telefone associados.
  • A execução das chamadas contra a Meta, usando o contexto do tenant identificado.

Fluxo de uma chamada típica

Cliente → [Authorization Header] → Hi Broker (HsmBackend)
                                         ↓
                                   Resolve TenantId
                                         ↓
                               wabaId (da rota) + TenantId
                                         ↓
                             Chama a Meta API com token gerenciado
                                         ↓
                              Retorna resposta ao cliente

2. Base URL e Swagger

URL Base

https://whatsapp-connect.hiplatform.com/hsmservices/api/public

Swagger (quando habilitado no ambiente)

Recurso URL
Interface interativa https://whatsapp-connect.hiplatform.com/hsmservices/swagger
Documento OpenAPI JSON https://whatsapp-connect.hiplatform.com/hsmservices/swagger/public-v1/swagger.json

O documento Swagger público é registrado como public-v1 com o título Hi Broker API.


3. Autenticação

Todos os endpoints exigem autenticação. Dois esquemas são suportados:

3.1 Basic Authentication

Credenciais codificadas em Base64 no formato username:password.

Authorization: Basic dXN1YXJpbzpzZW5oYQ==

Geração do valor em linha de comando:

echo -n "usuario:senha" | base64
# dXN1YXJpbzpzZW5oYQ==

3.2 DT-Fenix-Token

Token proprietário da plataforma Hi, usado quando a autenticação é feita via sistema integrado.

Authorization: DT-Fenix-Token P01_eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Importante: O backend usa o resultado da autenticação para identificar o TenantId. O wabaId informado na rota é combinado com esse tenant para validar e executar as chamadas contra a Meta.


4. Convenções e Padrões

Aspecto Regra
Content-Type (padrão) application/json
Content-Type (uploads) multipart/form-data
wabaId ID da WhatsApp Business Account (parâmetro de rota)
phoneNumberId ID do número de telefone WhatsApp Business (parâmetro de rota)
mediaId ID da mídia na Meta (parâmetro de rota)
id ID de recurso genérico na Meta — template, número de telefone etc.
Listas Seguem o formato Meta com data e paging quando aplicável
Campos e valores Seguem as regras da Meta WhatsApp Cloud API

5. Tratamento de Erros

Códigos HTTP

Status Descrição
400 Bad Request Payload inválido, campo obrigatório ausente ou erro de regra da Meta.
401 Unauthorized Credencial ausente ou inválida.
403 Forbidden Credencial válida, mas sem permissão para o recurso solicitado.
404 Not Found Recurso não encontrado ou não acessível para o tenant/WABA informados.
5xx Erro interno ou indisponibilidade de dependência externa.

Formato de erro (origem Meta)

Quando o erro vem da Meta, o corpo preserva o formato da integração:

{
  "error": {
    "message": "Invalid parameter",
    "type": "OAuthException",
    "code": 100
  }
}

6. Paginação

Endpoints de listagem usam paginação por cursor.

Parâmetros de query

Parâmetro Descrição
limit Quantidade máxima de itens por página. Padrão: 25.
after Cursor para avançar para a próxima página.
before Cursor para retroceder para a página anterior.

Formato da resposta paginada

{
  "data": [
    { "...": "..." }
  ],
  "paging": {
    "cursors": {
      "before": "QVFIUjhFY...",
      "after": "QVFIUjhFY..."
    },
    "next": "https://{host}/api/public/...",
    "previous": "https://{host}/api/public/..."
  }
}

Como navegar páginas

# Primeira página
GET /api/public/message_templates/{wabaId}?limit=10

# Próxima página (usando cursor "after" retornado)
GET /api/public/message_templates/{wabaId}?limit=10&after=QVFIUjhFY...

7. Referência de Endpoints


7.1 WABAs

Buscar WABA por ID

Retorna dados básicos de uma WhatsApp Business Account.

GET /api/public/wabas/{wabaId}

Parâmetros de rota:

Parâmetro Obrigatório Descrição
wabaId Sim ID da WABA.

Exemplo de requisição:

curl -X GET "https://{host}/api/public/wabas/123455667710" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "id": "123455667710",
  "name": "Minha Empresa LTDA",
  "marketing_messages_lite_api_status": "ONBOARDED",
  "currency": "BRL"
}

7.2 Números de Telefone

Listar números de telefone

Retorna os números comerciais associados à WABA.

GET /api/public/phone_numbers/{wabaId}?limit=25&after={cursor}&before={cursor}

Exemplo de requisição:

curl -X GET "https://{host}/api/public/phone_numbers/123455667710?limit=10" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "data": [
    {
      "id": "105981245678901",
      "display_phone_number": "+55 11 99999-9999",
      "verified_name": "Minha Empresa LTDA",
      "quality_rating": "GREEN",
      "status": "CONNECTED",
      "code_verification_status": "VERIFIED",
      "name_status": "APPROVED"
    }
  ],
  "paging": {
    "cursors": {
      "before": "QVFIUjhFY...",
      "after": "QVFIUjhFY..."
    }
  }
}

Buscar número por ID

GET /api/public/phone_numbers/{wabaId}/{id}

Exemplo de requisição:

curl -X GET "https://{host}/api/public/phone_numbers/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "id": "105981245678901",
  "display_phone_number": "+55 11 99999-9999",
  "verified_name": "Minha Empresa LTDA",
  "quality_rating": "GREEN",
  "status": "CONNECTED",
  "code_verification_status": "VERIFIED",
  "name_status": "APPROVED"
}

Atualizar nome de exibição

Atualiza o nome de exibição do número comercial. O nome está sujeito à aprovação da Meta.

POST /api/public/phone_numbers/{wabaId}/{phoneNumberId}/display_name

Payload:

{
  "name": "Minha Empresa Oficial"
}

Exemplo de requisição:

curl -X POST "https://{host}/api/public/phone_numbers/123455667710/105981245678901/display_name" \
  -H "Authorization: Basic {credentials}" \
  -H "Content-Type: application/json" \
  -d '{"name": "Minha Empresa Oficial"}'

Resposta 200:

{
  "success": true
}

7.3 Perfis Comerciais

Buscar perfil comercial

GET /api/public/business_profiles/{wabaId}/{phoneNumberId}?fields={campos}

O parâmetro fields é opcional. Valores aceitos separados por vírgula: about, address, description, email, profile_picture_url, websites, vertical.

Exemplo — buscar todos os campos:

curl -X GET "https://{host}/api/public/business_profiles/123455667710/105981245678901?fields=about,address,description,email,profile_picture_url,websites,vertical" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "data": [
    {
      "about": "Atendimento todos os dias das 8h às 20h",
      "address": "Av. Paulista, 1000 - Bela Vista, São Paulo/SP, 01310-100",
      "description": "Canal oficial de atendimento, vendas e suporte da empresa.",
      "email": "contato@empresa.com",
      "profile_picture_url": "https://lookaside.fbsbx.com/whatsapp_business_profile_photo.jpg",
      "websites": [
        "https://www.empresa.com",
        "https://instagram.com/empresa"
      ],
      "vertical": "PROF_SERVICES",
      "messaging_product": "whatsapp"
    }
  ]
}

Atualizar perfil comercial

POST /api/public/business_profiles/{wabaId}/{phoneNumberId}

Para atualizar a foto de perfil, primeiro faça upload via Uploads Resumíveis e use o handle retornado no campo profile_picture_handle.

Payload completo:

{
  "about": "Atendimento todos os dias das 8h às 20h",
  "address": "Av. Paulista, 1000 - Bela Vista, São Paulo/SP, 01310-100",
  "description": "Canal oficial de atendimento, vendas e suporte da empresa.",
  "email": "contato@empresa.com",
  "profile_picture_handle": "4::aW1hZ2UvanBlZw==::ARaExampleHandle",
  "vertical": "PROF_SERVICES",
  "websites": [
    "https://www.empresa.com",
    "https://instagram.com/empresa"
  ]
}

Valores aceitos para vertical: UNDEFINED, OTHER, AUTO, BEAUTY, APPAREL, EDU, ENTERTAIN, EVENT_PLAN, FINANCE, GROCERY, GOVT, HOTEL, HEALTH, NONPROFIT, PROF_SERVICES, RETAIL, TRAVEL, RESTAURANT, NOT_A_BIZ.

Resposta 200:

{
  "success": true
}

7.4 Mensagens

Enviar mensagem

Envia uma mensagem pelo número comercial informado.

POST /api/public/messages/{wabaId}/{phoneNumberId}

Campos comuns a todos os tipos:

Campo Obrigatório Descrição
messaging_product Sim Sempre "whatsapp".
recipient_type Não Tipo do destinatário. Valor padrão: "individual".
to Sim Número do destinatário no formato E.164 (ex.: "5511999999999").
type Sim Tipo da mensagem. Veja tabela abaixo.
context Não Objeto com message_id para responder a uma mensagem anterior.

Tipos de mensagem suportados:

type Descrição
text Texto simples
template Template de mensagem pré-aprovado
image Imagem (URL ou media_id)
document Documento (URL ou media_id)
video Vídeo (URL ou media_id)
audio Áudio (URL ou media_id)
sticker Figurinha
contacts Cartão de contato
reaction Reação com emoji
interactive Mensagem interativa com botões ou lista
location Localização geográfica

Payload: Mensagem de texto

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "text",
  "text": {
    "body": "Olá! Seu pedido #12345 foi confirmado.",
    "preview_url": false
  }
}

Payload: Mensagem de imagem por URL

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "image",
  "image": {
    "link": "https://www.empresa.com/imagens/banner-promocao.jpg",
    "caption": "Confira nossa promoção de verão! 🌞"
  }
}

Payload: Mensagem de imagem por media_id

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "image",
  "image": {
    "id": "4490709327384033",
    "caption": "Seu comprovante de pagamento."
  }
}

Payload: Mensagem de documento

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "document",
  "document": {
    "link": "https://www.empresa.com/docs/contrato.pdf",
    "filename": "Contrato_Servico.pdf",
    "caption": "Segue seu contrato para assinatura."
  }
}

Payload: Mensagem de áudio

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "audio",
  "audio": {
    "link": "https://www.empresa.com/audios/instrucoes.ogg"
  }
}

Payload: Mensagem de vídeo

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "video",
  "video": {
    "link": "https://www.empresa.com/videos/tutorial.mp4",
    "caption": "Veja como usar nosso aplicativo."
  }
}

Payload: Reação a mensagem

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "reaction",
  "reaction": {
    "message_id": "wamid.HBgMNTUxMTk5OTk5OTk5FQIAERgSMkY4QTY4Q0I0QzQxRUI0AA==",
    "emoji": "👍"
  }
}

Payload: Localização

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "location",
  "location": {
    "longitude": -46.6333,
    "latitude": -23.5505,
    "name": "Av. Paulista, 1000",
    "address": "Av. Paulista, 1000 - Bela Vista, São Paulo - SP, 01310-100"
  }
}

Payload: Mensagem interativa — Botões

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "interactive",
  "interactive": {
    "type": "button",
    "body": {
      "text": "Você gostaria de confirmar seu agendamento para amanhã às 14h?"
    },
    "action": {
      "buttons": [
        {
          "type": "reply",
          "reply": {
            "id": "confirm_yes",
            "title": "✅ Confirmar"
          }
        },
        {
          "type": "reply",
          "reply": {
            "id": "confirm_no",
            "title": "❌ Cancelar"
          }
        }
      ]
    }
  }
}

Payload: Mensagem interativa — Lista

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "interactive",
  "interactive": {
    "type": "list",
    "header": {
      "type": "text",
      "text": "Escolha um departamento"
    },
    "body": {
      "text": "Selecione o setor com o qual deseja falar:"
    },
    "footer": {
      "text": "Horário de atendimento: 8h às 20h"
    },
    "action": {
      "button": "Ver opções",
      "sections": [
        {
          "title": "Atendimento",
          "rows": [
            {
              "id": "dept_suporte",
              "title": "Suporte técnico",
              "description": "Problemas com produtos ou serviços"
            },
            {
              "id": "dept_financeiro",
              "title": "Financeiro",
              "description": "Cobranças, faturas e pagamentos"
            }
          ]
        },
        {
          "title": "Vendas",
          "rows": [
            {
              "id": "dept_comercial",
              "title": "Comercial",
              "description": "Novos contratos e propostas"
            }
          ]
        }
      ]
    }
  }
}

Payload: Mensagem de template

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "template",
  "template": {
    "name": "reserva_confirmada",
    "language": {
      "code": "pt_BR"
    },
    "components": [
      {
        "type": "body",
        "parameters": [
          {
            "type": "text",
            "text": "Maria Silva"
          },
          {
            "type": "text",
            "text": "15/07/2025 às 14h00"
          }
        ]
      }
    ]
  }
}

Payload: Resposta a uma mensagem (contexto)

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "text",
  "context": {
    "message_id": "wamid.HBgMNTUxMTk5OTk5OTk5FQIAERgSMkY4QTY4Q0I0QzQxRUI0AA=="
  },
  "text": {
    "body": "Claro! Posso te ajudar com isso.",
    "preview_url": false
  }
}

Resposta 200 (todos os tipos de mensagem):

{
  "messaging_product": "whatsapp",
  "contacts": [
    {
      "input": "5511999999999",
      "wa_id": "5511999999999"
    }
  ],
  "messages": [
    {
      "id": "wamid.HBgMNTUxMTk5OTk5OTk5FQIAERgSMkY4QTY4Q0I0QzQxRUI0AA==",
      "message_status": "accepted"
    }
  ]
}

7.5 Mensagens de Marketing

Envia mensagens de template com foco em marketing. O endpoint segue o mesmo padrão de mensagens, mas é específico para campanhas.

POST /api/public/marketing_messages/{wabaId}/{phoneNumberId}

Payload:

{
  "messaging_product": "whatsapp",
  "recipient_type": "individual",
  "to": "5511999999999",
  "type": "template",
  "template": {
    "name": "campanha_verao_2025",
    "language": {
      "code": "pt_BR"
    },
    "components": [
      {
        "type": "header",
        "parameters": [
          {
            "type": "image",
            "image": {
              "id": "4490709327384033"
            }
          }
        ]
      },
      {
        "type": "body",
        "parameters": [
          {
            "type": "text",
            "parameter_name": "first_name",
            "text": "Jessica"
          },
          {
            "type": "text",
            "parameter_name": "order_number",
            "text": "SKBUP2-4CPIG9"
          }
        ]
      }
    ]
  }
}

A resposta 200 segue o mesmo formato do endpoint de envio de mensagens.


7.6 Mídias

Enviar mídia (upload)

Faz upload de um arquivo de mídia para a Meta. O id retornado pode ser usado em envios de mensagens com mídia.

POST /api/public/media/{wabaId}/{phoneNumberId}
Content-Type: multipart/form-data
Campo Obrigatório Descrição
file Sim Arquivo binário (imagem, vídeo, documento, áudio).

Exemplo com curl:

curl -X POST "https://{host}/api/public/media/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -F "file=@./banner-promocao.jpg"

Resposta 200:

{
  "id": "4490709327384033"
}

Use o id retornado no campo image.id, document.id, video.id ou audio.id ao enviar mensagens.


Buscar informações de mídia

GET /api/public/media/{wabaId}/{phoneNumberId}/{mediaId}

Exemplo:

curl -X GET "https://{host}/api/public/media/123455667710/105981245678901/4490709327384033" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "id": "4490709327384033",
  "url": "https://lookaside.fbsbx.com/whatsapp_business/attachments/?mid=4490709327384033",
  "mime_type": "image/jpeg",
  "sha256": "e3b0c44298fc1c149afbf4c8996fb924",
  "file_size": 245612,
  "messaging_product": "whatsapp"
}

Excluir mídia

DELETE /api/public/media/{wabaId}/{phoneNumberId}/{mediaId}

Exemplo:

curl -X DELETE "https://{host}/api/public/media/123455667710/105981245678901/4490709327384033" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "success": true
}

7.7 Uploads Resumíveis

Cria uma sessão de upload na Meta e envia o arquivo. O handle retornado é necessário para operações que exigem referência a mídia, como a atualização de foto de perfil.

POST /api/public/uploads/{wabaId}/{phoneNumberId}
Content-Type: multipart/form-data
Campo Obrigatório Descrição
file Sim Arquivo binário.

Exemplo:

curl -X POST "https://{host}/api/public/uploads/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -F "file=@./foto-perfil.jpg"

Resposta 200:

{
  "h": "4::aW1hZ2UvanBlZw==::ARaExampleHandle"
}

Use o valor de h no campo profile_picture_handle ao atualizar o perfil comercial, ou em header_handle ao criar templates com header de imagem, vídeo ou documento.


7.8 Templates de Mensagem

Listar templates

GET /api/public/message_templates/{wabaId}?name={name}&language={language}&status={status}&category={category}&limit=25&after={cursor}&before={cursor}

Filtros disponíveis:

Parâmetro Descrição Exemplo
name Nome do template reserva_confirmada
language Idioma pt_BR, en_US
status Status de aprovação APPROVED, PENDING, REJECTED
category Categoria UTILITY, MARKETING, AUTHENTICATION
limit Itens por página 10
after / before Cursor de paginação

Exemplo:

curl -X GET "https://{host}/api/public/message_templates/123455667710?status=APPROVED&category=UTILITY&limit=10" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "data": [
    {
      "id": "1387372356726668",
      "name": "reserva_confirmada",
      "language": "pt_BR",
      "status": "APPROVED",
      "category": "UTILITY",
      "parameter_format": "NAMED",
      "components": [
        {
          "type": "BODY",
          "text": "Sua reserva para {{number_of_guests}} pessoas está confirmada para {{date}} às {{time}}."
        }
      ]
    }
  ],
  "paging": {
    "cursors": {
      "before": "QVFIU...",
      "after": "QVFIU..."
    }
  }
}

Buscar template por ID

GET /api/public/message_templates/{wabaId}/{id}

Resposta 200:

{
  "id": "1387372356726668",
  "name": "reserva_confirmada",
  "language": "pt_BR",
  "status": "APPROVED",
  "category": "UTILITY",
  "parameter_format": "NAMED",
  "components": [
    {
      "type": "BODY",
      "text": "Sua reserva para {{number_of_guests}} pessoas está confirmada para {{date}} às {{time}}."
    }
  ]
}

Criar template

POST /api/public/message_templates/{wabaId}

Resposta 200:

{
  "id": "1387372356726668",
  "status": "PENDING",
  "category": "UTILITY"
}

Templates ficam com status PENDING até a análise da Meta. Após aprovação, o status passa para APPROVED.


Variações de payload — Criação de template

Template com parâmetros posicionais (texto)

Parâmetros no formato {{1}}, {{2}} etc. Use parameter_format: "POSITIONAL".

{
  "name": "lembrete_cupom_expirar",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "MARKETING",
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Corra, {{1}}!",
      "example": {
        "header_text": ["Ana"]
      }
    },
    {
      "type": "BODY",
      "text": "Seu cupom {{1}} expira em {{2}} dias. Não perca!",
      "example": {
        "body_text": [["VERAO20", "3"]]
      }
    },
    {
      "type": "FOOTER",
      "text": "Minha Empresa LTDA"
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "URL",
          "text": "Ver ofertas",
          "url": "https://www.empresa.com/ofertas"
        },
        {
          "type": "QUICK_REPLY",
          "text": "Não tenho interesse"
        }
      ]
    }
  ]
}

Template com parâmetros nomeados

Use parameter_format: "NAMED" com placeholders como {{customer_name}}.

{
  "name": "confirmacao_reserva_nomeada",
  "parameter_format": "NAMED",
  "language": "pt_BR",
  "category": "UTILITY",
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Reserva confirmada para {{customer_name}}",
      "example": {
        "header_text_named_params": [
          { "param_name": "customer_name", "example": "Carlos Souza" }
        ]
      }
    },
    {
      "type": "BODY",
      "text": "Sua mesa para {{number_of_guests}} pessoas está reservada para {{date}} às {{time}}.",
      "example": {
        "body_text_named_params": [
          { "param_name": "number_of_guests", "example": "4" },
          { "param_name": "date", "example": "20 de julho de 2025" },
          { "param_name": "time", "example": "19h30" }
        ]
      }
    }
  ]
}

Template com header de imagem

Necessita de um header_handle gerado pelo endpoint de Uploads Resumíveis.

{
  "name": "nova_campanha_imagem",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "MARKETING",
  "components": [
    {
      "type": "HEADER",
      "format": "IMAGE",
      "example": {
        "header_handle": ["4::aW1hZ2UvanBlZw==::ARaExampleHandle"]
      }
    },
    {
      "type": "BODY",
      "text": "Olá, {{1}}! Confira nossa nova campanha de verão.",
      "example": {
        "body_text": [["Ana"]]
      }
    }
  ]
}

Template com header de vídeo

{
  "name": "novidades_semana_video",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "MARKETING",
  "components": [
    {
      "type": "HEADER",
      "format": "VIDEO",
      "example": {
        "header_handle": ["4::dmlkZW8vbXA0::ARaExampleHandle"]
      }
    },
    {
      "type": "BODY",
      "text": "Assista ao vídeo com as novidades desta semana."
    }
  ]
}

Template com header de documento

{
  "name": "documento_disponivel",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "UTILITY",
  "components": [
    {
      "type": "HEADER",
      "format": "DOCUMENT",
      "example": {
        "header_handle": ["4::YXBwbGljYXRpb24vcGRm::ARaExampleHandle"]
      }
    },
    {
      "type": "BODY",
      "text": "Seu documento está disponível para consulta."
    }
  ]
}

Template com header de localização

{
  "name": "localizacao_atendimento",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "UTILITY",
  "components": [
    {
      "type": "HEADER",
      "format": "LOCATION"
    },
    {
      "type": "BODY",
      "text": "Use a localização abaixo para chegar ao nosso endereço de atendimento."
    }
  ]
}

Template com URL dinâmica

Use {{1}} na URL para parte do link ser preenchida no momento do envio.

{
  "name": "oferta_exclusiva_url_dinamica",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "MARKETING",
  "components": [
    {
      "type": "BODY",
      "text": "Acesse sua oferta exclusiva personalizada."
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "URL",
          "text": "Ver minha oferta",
          "url": "https://www.empresa.com/ofertas/{{1}}",
          "example": ["cliente-98765"]
        }
      ]
    }
  ]
}

Template com botão de telefone

{
  "name": "contato_suporte_telefone",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "UTILITY",
  "components": [
    {
      "type": "BODY",
      "text": "Precisa de ajuda? Nossa equipe está disponível para atender você."
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "PHONE_NUMBER",
          "text": "Ligar agora",
          "phone_number": "+5511999999999"
        }
      ]
    }
  ]
}

Template com botão de copiar código

{
  "name": "cupom_desconto_copiar",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "MARKETING",
  "components": [
    {
      "type": "BODY",
      "text": "Use o cupom abaixo para concluir sua compra com 20% de desconto."
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "COPY_CODE",
          "text": "Copiar cupom"
        }
      ]
    }
  ]
}

Template com botão de detalhes do pedido

Requer que o fluxo de comércio da Meta esteja habilitado para a conta.

{
  "name": "atualizacao_pedido",
  "parameter_format": "POSITIONAL",
  "language": "pt_BR",
  "category": "UTILITY",
  "components": [
    {
      "type": "BODY",
      "text": "Seu pedido foi atualizado. Toque no botão abaixo para ver os detalhes."
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "ORDER_DETAILS",
          "text": "Ver pedido"
        }
      ]
    }
  ]
}

Template de autenticação com botão OTP de copiar código

{
  "name": "auth_login_otp_copycode_hmg_v1",
  "language": "pt_BR",
  "category": "AUTHENTICATION",
  "components": [
    {
      "type": "BODY",
      "add_security_recommendation": true,
      "code_expiration_minutes": 5
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "OTP",
          "otp_type" : "COPY_CODE",
          "text": "Copiar código"
        }
      ]
    }
  ]
}

Template de autenticação com botão de OTP preenchimento automático com toque

{
  "name": "authentication_code_autofill_buttonpt12",
  "language": "pt_BR",
  "category": "AUTHENTICATION",
  "components": [
    {
      "type": "BODY",
      "add_security_recommendation": true
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "OTP",
          "otp_type" : "ONE_TAP",
          "text": "Copy Code",
          "autofill_text": "Autofill", 
          "package_name": "com.example.luckyshrub", 
          "signature_hash": "K8a/AINcGX7", 
          "supported_apps": [ 
            { 
               "package_name": "com.example.luckyshrub", 
               "signature_hash": "K8a/AINcGX7" 
            }
          ]
        }
      ]
    }
  ]
}

Template de autenticação com botão OTP de preenchimento automático sem toque

{
  "name": "zero_tap_auth_hmg_v1",
  "language": "pt_BR",
  "category": "AUTHENTICATION",
  "message_send_ttl_seconds": 60,
  "components": [
    {
      "type": "BODY",
      "add_security_recommendation": true
    },
    { 
      "type": "FOOTER", 
      "code_expiration_minutes": 5,
    },
    {
      "type": "BUTTONS",
      "buttons": [
        {
          "type": "OTP",
          "otp_type" : "NO_TAP",
          "text": "Copy Code",
          "autofill_text": "Autofill", 
          "zero_tap_terms_accepted": true,
          "supported_apps": [ 
            { 
               "package_name": "com.example.luckyshrub", 
               "signature_hash": "K8a/AINcGX7" 
            }
          ]
        }
      ]
    }
  ]
}

Atualizar template

Permite atualizar os componentes de um template existente.

PATCH /api/public/message_templates/{wabaId}/{id}

Payload:

{
  "components": [
    {
      "type": "HEADER",
      "format": "TEXT",
      "text": "Nossa {{1}} começou!",
      "example": {
        "header_text": ["Liquidação de Inverno"]
      }
    },
    {
      "type": "BODY",
      "text": "Compre até {{1}} e use o código {{2}} para obter {{3}} de desconto.",
      "example": {
        "body_text": [
          ["31 de julho", "INVERNO30", "30%"]
        ]
      }
    }
  ]
}

Resposta 200:

{
  "success": true
}

Excluir template por nome

DELETE /api/public/message_templates/{wabaId}?name={name}

Exemplo:

curl -X DELETE "https://{host}/api/public/message_templates/123455667710?name=lembrete_cupom_expirar" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "success": true
}

Excluir template por ID

DELETE /api/public/message_templates/{wabaId}/{id}?name={name}

O parâmetro name é obrigatório na query string mesmo ao deletar por ID, pois a Meta pode ter múltiplos templates com o mesmo nome em idiomas distintos.

Exemplo:

curl -X DELETE "https://{host}/api/public/message_templates/123455667710/1387372356726668?name=lembrete_cupom_expirar" \
  -H "Authorization: Basic {credentials}"

Resposta 200:

{
  "success": true
}

7.9 Migração de Templates

Migra templates de uma WABA de origem para a WABA de destino informada na rota. Útil em cenários de consolidação de contas ou reestruturação de WABAs.

POST /api/public/migrate_message_templates/{wabaId}

Payload:

{
  "source_waba_id": "102290129340398",
  "page_number": 0,
  "count": 2,
  "template_ids": [
    "1473688840035974",
    "6162904357082268"
  ]
}
Campo Obrigatório Descrição
source_waba_id Sim ID da WABA de origem dos templates.
page_number Não Página dos templates a migrar (paginação).
count Não Quantidade de templates a migrar por chamada.
template_ids Não Lista de IDs específicos a migrar. Se omitido, migra todos.

Resposta 200:

{
  "migrated_templates": [
    "1473688840035974",
    "6162904357082268"
  ],
  "failed_templates": {
    "572279198452421": "Incorrect category"
  }
}

7.10 Usernames

Adicionar username

Solicita um username para o número de telefone comercial.

POST /api/public/usernames/{wabaId}/{phoneNumberId}

Payload:

{
  "username": "minhaempresa.oficial"
}

Resposta 200:

{
  "status": "approved"
}

Buscar sugestões de username

Retorna sugestões disponíveis com base no número informado.

POST /api/public/usernames/{wabaId}/{phoneNumberId}/suggestions

Este endpoint não requer body.

Resposta 200:

{
  "data": [
    {
      "reserved_username": [
        "minhaempresa.oficial",
        "minhaempresa.br",
        "minhaempresa.suporte"
      ]
    }
  ]
}

Excluir username

DELETE /api/public/usernames/{wabaId}/{phoneNumberId}

Resposta 200:

true

8. Exemplos de Integração Completa

Fluxo 1: Enviar mensagem de texto simples

curl -X POST "https://{host}/api/public/messages/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": "5511999999999",
    "type": "text",
    "text": {
      "body": "Olá! Esta é uma mensagem enviada pelo Hi Broker.",
      "preview_url": false
    }
  }'

Fluxo 2: Upload de mídia e envio como imagem

Passo 1 — Upload do arquivo:

curl -X POST "https://{host}/api/public/media/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -F "file=@./banner.jpg"
# Retorna: {"id": "4490709327384033"}

Passo 2 — Envio da mensagem com a mídia:

curl -X POST "https://{host}/api/public/messages/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": "5511999999999",
    "type": "image",
    "image": {
      "id": "4490709327384033",
      "caption": "Confira nossa promoção!"
    }
  }'

Fluxo 3: Criar template e usar em envio

Passo 1 — Criar template:

curl -X POST "https://{host}/api/public/message_templates/123455667710" \
  -H "Authorization: Basic {credentials}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "boas_vindas_cliente",
    "parameter_format": "NAMED",
    "language": "pt_BR",
    "category": "UTILITY",
    "components": [
      {
        "type": "BODY",
        "text": "Olá, {{customer_name}}! Seja bem-vindo(a) à Minha Empresa. Seu código de cliente é {{customer_code}}.",
        "example": {
          "body_text_named_params": [
            { "param_name": "customer_name", "example": "Carlos" },
            { "param_name": "customer_code", "example": "CLI-001" }
          ]
        }
      }
    ]
  }'
# Retorna: {"id": "9988776655443322", "status": "PENDING", "category": "UTILITY"}

Passo 2 — Aguardar aprovação (status APPROVED) e enviar:

curl -X POST "https://{host}/api/public/messages/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -H "Content-Type: application/json" \
  -d '{
    "messaging_product": "whatsapp",
    "recipient_type": "individual",
    "to": "5511999999999",
    "type": "template",
    "template": {
      "name": "boas_vindas_cliente",
      "language": { "code": "pt_BR" },
      "components": [
        {
          "type": "body",
          "parameters": [
            { "type": "text", "parameter_name": "customer_name", "text": "Carlos" },
            { "type": "text", "parameter_name": "customer_code", "text": "CLI-001" }
          ]
        }
      ]
    }
  }'

Fluxo 4: Upload resumível + atualização de foto de perfil

Passo 1 — Upload resumível:

curl -X POST "https://{host}/api/public/uploads/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -F "file=@./logo-empresa.jpg"
# Retorna: {"h": "4::aW1hZ2UvanBlZw==::ARaExampleHandle"}

Passo 2 — Atualizar perfil:

curl -X POST "https://{host}/api/public/business_profiles/123455667710/105981245678901" \
  -H "Authorization: Basic {credentials}" \
  -H "Content-Type: application/json" \
  -d '{
    "about": "Atendimento de segunda a sábado, das 8h às 18h.",
    "profile_picture_handle": "4::aW1hZ2UvanBlZw==::ARaExampleHandle"
  }'

9. Referências Meta

Recurso Link
WhatsApp Cloud API — Messages https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages/
WhatsApp Cloud API — Media https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media/
Business Management API — Message Templates https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/
WhatsApp Business Profiles https://developers.facebook.com/docs/whatsapp/cloud-api/reference/business-profiles/

10. Webhooks

Este recurso foi desenvolvido para receber, processar e encaminhar ao Webhook do cliente as mensagens recebidas da Meta (WhatsApp Business Platform), enviadas por usuários finais para o número de WhatsApp integrado.

Sempre que um cliente final envia uma mensagem pelo WhatsApp, a Meta repassa esse conteúdo para nosso sistema. Nós tratamos os dados recebidos e encaminhamos o evento para o Webhook configurado pelo cliente.

Formato enviado ao Webhook

Sempre que ocorrer um evento, seu endpoint de Webhook receberá um JSON com a seguinte estrutura:


{
   "id":"7e5f5c77-3e65-4d53-9f8b-123456789abc",
   "tenantId":"11111111-2222-3333-4444-555555555555",
   "departmentId":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
   "destinationDepartmentId":"bbbbbbbb-cccc-dddd-eeee-ffffffffffff",
   "senderId":"5511999999999",
   "consumerId":"5511888888888",
   "consumerName":"João da Silva",
   "accountId":"99999999-8888-7777-6666-555555555555",
   "orderGaranteeFlag":true,
   "payload":{
      "/* Ver formatos possíveis em Formatos de Payload */"
   },
   "repliedMessageId":"abcd1234efgh5678",
   "brokerTypeOrigin":"Meta",
   "customerIdentificationProperties":[
      {
         "name":"cpf",
         "value":"12345678900"
      },
      {
         "name":"email",
         "value":"joao.silva@exemplo.com"
      }
   ],
   "customProperties":[
      {
         "name":"canal",
         "value":"whatsapp"
      }
   ],
   "adProperties":[
      {
         "name":"campaignId",
         "value":"cmp_001"
      }
   ]
}

Estrutura do Payload

Campo Tipo Descrição
id GUID Identificador único da mensagem.
tenantId GUID Identificador do site/tenant.
departmentId GUID Departamento que recebeu a mensagem.
destinationDepartmentId GUID Departamento de destino, se houver roteamento.
senderId string Identificador do remetente no contexto do canal.
consumerId string Identificador do consumidor/usuário final.
consumerName string Nome do consumidor, quando disponível.
accountId GUID Conta associada ao atendimento.
orderGaranteeFlag boolean Indica se a resposta garantirá ordenação.
payload Object Conteúdo da mensagem. Um dos formatos listados na seção “Formatos de Payload".
brokerTypeOrigin string/enum Origem/broker do evento (ex.: Meta)
customerIdentificationProperties Object List Propriedades de identificação do usuário (chave/valor)
customProperties Object List Propriedades adicionais associadas ao cliente.
adProperties Object List Propriedades relacionadas a anúncios/campanhas de origem.

Formatos de Payload

O campo payload no JSON enviado pelo Webhook pode variar conforme o tipo de conteúdo. Abaixo estão os formatos possíveis e suas regras:

Texto

Campo Tipo
body string
previewFirstUrl boolean
identifier string
data string

Imagem

Campo Tipo
imageType string
url string
caption string
contentType string

Áudio

Campo Tipo
audioType string
url string
contentType string

Vídeo

Campo Tipo
videoType string
url string
caption string
contentType string

Documento

Campo Tipo
documentType string
url string
caption string
filename string
contentType string