Documentação para integrações externas

Integrações — API Externa

Base URL: {{API_URL}}/external-api

Todos os endpoints protegidos exigem o header Authorization: Bearer <token>.

  • Integration Token: Entre em contato para obter.
  • Public: endpoint público, não requer autenticação.

Visão Geral

Fluxos gerais para recuperar, encerrar ou encaminhar conversas em andamento.

Buscar conversa

GET /chats/:id

Retorna os detalhes e histórico de mensagens de uma conversa pelo ID interno.

Autenticação: Integration Token

Parâmetros:

NomeLocalTipoObrigatórioDescrição
idPathnumberSimIdentificador numérico da conversa.

Exemplo de requisição:

curl -X GET '{{API_URL}}/external-api/chats/1234' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>'

Resposta esperada:

{
  "status": 200,
  "data": {
    "uuid": "9f1d4c3a-5211-4af7-9f32-ff932c9c1234",
    "telefone": "+5511999999999",
    "status": "aberta",
    "mensagens": [
      {
        "uuid": "a4f9f1a1-c555-4b0a-8d55-1e42f88f6bca",
        "tipo": "texto",
        "texto": "Olá, posso ajudar?",
        "criado_em": "2024-04-15T12:30:00.000Z",
        "origem": "agente"
      }
    ]
  }
}

Observações:

  • Retorna status 404 caso a conversa não exista.

Transferir conversa

POST /chats/:id/transfer

Encaminha uma conversa para outro setor e, opcionalmente, envia uma mensagem de transferência.

Autenticação: Integration Token

Parâmetros:

NomeLocalTipoObrigatórioDescrição
idPathnumberSimIdentificador numérico da conversa.
setor_idBodystring | numberSimID do setor de destino.
enviar_mensagemBodybooleanNãoEnvia mensagem automática avisando o cliente sobre a transferência.

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/chats/1234/transfer' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "setor_id": 5,
    "enviar_mensagem": true
  }'

Resposta esperada:

{
  "status": 200
}

Observações:

  • Retorna status 404 caso a conversa ou o setor não existam.

Encerrar conversa

POST /chats/:id/close

Encerra uma conversa aberta e retorna os dados principais do registro.

Autenticação: Integration Token

Parâmetros:

NomeLocalTipoObrigatórioDescrição
idPathnumberSimIdentificador numérico da conversa.

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/chats/1234/close' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>'

Resposta esperada:

{
  "status": 200,
  "data": {
    "uuid": "9f1d4c3a-5211-4af7-9f32-ff932c9c1234",
    "telefone": "+5511999999999",
    "status": "encerrada"
  }
}

Tags

Gerenciamento de tags para organização e categorização de conversas.

Listar tags

GET /tags

Retorna a lista de tags configuradas na conta.

Autenticação: Integration Token

Exemplo de requisição:

curl -X GET '{{API_URL}}/external-api/tags' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>'

Resposta esperada:

{
  "status": 200,
  "data": [
    { "id": 10, "nome": "VIP", "cor": "#0EA5E9" },
    { "id": 11, "nome": "Black Friday", "cor": "#F97316" }
  ]
}

Atualizar tags da conversa

PATCH /chats/:id

Atualiza as tags vinculadas à conversa. Use IDs separados por vírgula.

Autenticação: Integration Token

Parâmetros:

NomeLocalTipoObrigatórioDescrição
idPathnumberSimIdentificador numérico da conversa.
tagsBodystringNãoLista de IDs de tags separadas por vírgula.

Exemplo de requisição:

curl -X PATCH '{{API_URL}}/external-api/chats/1234' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "tags": "12,45,77"
  }'

Resposta esperada:

{
  "status": 200
}

Fluxos

Recursos auxiliares para recuperar dados de fluxos disponíveis.

Listar fluxos

GET /flows

Lista os fluxos (flows) disponíveis para disparo via API.

Autenticação: Integration Token

Exemplo de requisição:

curl -X GET '{{API_URL}}/external-api/flows' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>'

Resposta esperada:

{
  "status": 200,
  "data": [
    {
      "id": 21,
      "uuid": "c8866243-22cf-4b3d-9cb5-ced9d5f4db44",
      "nome": "Fluxo de Boas-vindas",
      "status": "PUBLISHED",
      "flow_id": "1234567890"
    }
  ]
}

Observações:

  • Apenas fluxos publicados podem ser enviados.

Mensagens

Envio de mensagens de texto, templates, imagens, documentos e flows.

Enviar template de texto

POST /messages/send/text/template

Dispara um template aprovado do WhatsApp com variáveis opcionais.

Autenticação: Integration Token
Content-Type: application/json

Parâmetros:

NomeLocalTipoObrigatórioDescrição
canal_idBodynumberNãoID do canal Meta. Se omitido, o sistema tenta localizar um canal preferencial.
contato_idBodynumberNãoID do contato. Necessário se não informar telefone.
contato_nomeBodystringNãoNome do contato para personalização.
contato_telefoneBodystringNãoTelefone completo com DDI.
modelo_idBodynumberSimIdentificador do template aprovado.
modelo_variaveisBodystring[]SimValores que serão injetados nas variáveis do template na ordem correta.
botao_variaveisBodystring[]NãoValores para botões com variáveis (quando houver).
statusBody"aberta" | "encerrada"NãoStatus esperado para a conversa criada/localizada.

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/messages/send/text/template' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "modelo_id": 42,
    "contato_nome": "João Silva",
    "contato_telefone": "+5511999999999",
    "modelo_variaveis": ["João", "pedido #123"],
    "botao_variaveis": ["https://sua-url.com/pedido/123"]
  }'

Resposta esperada:

{
  "status": 200,
  "data": {
    "uuid": "a1b2c3d4-e5f6-7890-abcd-1234567890ab",
    "texto": "Olá João, seu pedido #123 está confirmado!",
    "status": "aberta",
    "conversa_uuid": "9f1d4c3a-5211-4af7-9f32-ff932c9c1234"
  }
}

Observações:

  • Garantir que o template esteja aprovado e publicado antes do envio.

Enviar mensagem de texto

POST /messages/send/text

Envia uma mensagem de texto simples para um contato existente ou recém-criado.

Autenticação: Integration Token
Content-Type: application/json

Parâmetros:

NomeLocalTipoObrigatórioDescrição
canal_idBodynumberSimID do canal por onde a mensagem será enviada.
telefoneBodystringSimTelefone completo com DDI.
textoBodystringSimMensagem a ser enviada.
contato_nomeBodystringNãoNome do contato. Ajuda a criar a conversa caso ela não exista.
statusBody"aberta" | "encerrada"NãoStatus desejado para a conversa ao enviar a mensagem.

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/messages/send/text' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "canal_id": 12,
    "telefone": "+5511999999999",
    "texto": "Olá, tudo bem?",
    "contato_nome": "João Silva"
  }'

Resposta esperada:

{
  "status": 200
}

Observações:

  • Retorna 200 mesmo quando a conversa não existe; nesse caso a mensagem será criada ao localizar/abrir a conversa.

Enviar imagem

POST /messages/send/image

Envia uma imagem para uma conversa ativa. Necessita do arquivo em multipart/form-data.

Autenticação: Integration Token
Content-Type: multipart/form-data

Parâmetros:

NomeLocalTipoObrigatórioDescrição
canal_idBodynumberSimID do canal por onde a mensagem será enviada.
telefoneBodystringSimTelefone completo com DDI.
legendaBodystringNãoLegenda opcional para a imagem.
fileBodyFileSimArquivo da imagem (jpeg, png, etc).

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/messages/send/image' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -F 'canal_id=12' \
  -F 'telefone=+5511999999999' \
  -F 'legenda=Catálogo atualizado' \
  -F 'file=@/path/imagem.jpg'

Resposta esperada:

{
  "status": 200
}

Observações:

  • Retorna 404 se a conversa não estiver aberta.

Enviar documento

POST /messages/send/document

Envia arquivos PDF, DOCX, PPTX ou XLSX para conversas abertas.

Autenticação: Integration Token
Content-Type: multipart/form-data

Parâmetros:

NomeLocalTipoObrigatórioDescrição
canal_idBodynumberSimID do canal por onde a mensagem será enviada.
telefoneBodystringSimTelefone completo com DDI.
legendaBodystringNãoLegenda opcional para o documento.
fileBodyFileSimArquivo do documento (pdf, docx, pptx, xlsx).

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/messages/send/document' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -F 'canal_id=12' \
  -F 'telefone=+5511999999999' \
  -F 'file=@/path/contrato.pdf' \
  -F 'legenda=Contrato atualizado'

Resposta esperada:

{
  "status": 200
}

Observações:

  • Canais Instagram não aceitam envio de documentos e retornam status 400.

Enviar flow Meta

POST /messages/send/flow

Dispara um Flow Meta (experience) para o contato informado.

Autenticação: Integration Token
Content-Type: application/json

Parâmetros:

NomeLocalTipoObrigatórioDescrição
flow_idBodystringSimUUID interno do Flow ou flow_id retornado pelo Meta.
contato_idBodynumberNãoID do contato existente. Alternativa ao contato_telefone.
contato_telefoneBodystringNãoTelefone completo com DDI para localizar/criar o contato.
contato_nomeBodystringNãoNome do contato quando o telefone for informado.
canal_idBodynumberNãoID do canal Meta. Se omitido, o sistema tenta encontrar um canal Meta preferencial.
header_textBodystringNãoTexto opcional exibido no cabeçalho do Flow.
body_textBodystringSimConteúdo principal apresentado ao cliente.
footer_textBodystringNãoTexto exibido no rodapé.
cta_textBodystringNãoRótulo do botão de CTA. Padrão: "Abrir".
flow_action_dataBodyobjectNãoPayload opcional enviado ao Flow.

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/messages/send/flow' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "flow_id": "flow_1234567890",
    "contato_telefone": "+5511999999999",
    "contato_nome": "João Silva",
    "body_text": "Quais produtos você gostaria de receber?",
    "header_text": "Bem-vindo!",
    "cta_text": "Responder"
  }'

Resposta esperada:

{
  "status": 200,
  "message": "Flow enviado com sucesso",
  "data": {
    "wamid": "wamid.HBgMNTUxMTIzNDU2Nzg5FQIAERgSMzA1RDg2OEZGN0NBRTgxRjYwAA==",
    "mensagem_uuid": "1587d5b1-7e9e-41a7-ae3f-26022db5ce5b",
    "conversa_uuid": "9f1d4c3a-5211-4af7-9f32-ff932c9c1234",
    "flow_id": "flow_1234567890"
  }
}

Observações:

  • Somente canais Meta são suportados.
  • Se o flow estiver como rascunho será retornado status 400.

Upload de mídia

POST /messages/upload/media

Faz upload de uma imagem para o servidor e retorna o media_id do Meta.

Autenticação: Integration Token
Content-Type: multipart/form-data

Parâmetros:

NomeLocalTipoObrigatórioDescrição
canal_idBodystringSimID do canal Meta onde a mídia será hospedada.
fileBodyFileSimArquivo de imagem a ser enviado.

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/messages/upload/media' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -F 'canal_id=12' \
  -F 'file=@/path/imagem.jpg'

Resposta esperada:

{
  "status": 200,
  "data": "<media_id>"
}

Contatos

Criação e busca de contatos para garantir consistência ao enviar mensagens.

Criar ou localizar contato

POST /contacts/create

Localiza um contato existente ou cria um novo registro vinculado ao telefone informado.

Autenticação: Integration Token
Content-Type: application/json

Parâmetros:

NomeLocalTipoObrigatórioDescrição
nameBodystringSimNome completo do contato.
phoneBodystringSimTelefone completo com DDI.

Exemplo de requisição:

curl -X POST '{{API_URL}}/external-api/contacts/create' \
  -H 'Authorization: Bearer <INTEGRATION_TOKEN>' \
  -H 'Content-Type: application/json' \
  --data-raw '{
    "name": "João Silva",
    "phone": "+5511999999999"
  }'

Resposta esperada:

{
  "response": true,
  "data": {
    "id": 987,
    "uuid": "d9f52b2f-1079-4f7c-92fb-792ab4d19e11",
    "nome": "João Silva",
    "telefone": "+5511999999999",
    "criado_em": "2024-04-12T10:15:00.000Z"
  }
}

DTOs de referência

ExternalApiMessageTextSendDto

{
  canal_id: number;           // ID do canal
  telefone: string;           // Telefone com DDI
  texto?: string;             // Texto da mensagem
  contato_nome?: string;      // Nome do contato
  status?: 'aberta' | 'encerrada';
  origem?: 'sistema' | 'api' | 'coexistencia';
  setor_id?: number;
}

ExternalApiMessageImageSendDto

{
  canal_id: number;
  telefone: string;
  legenda?: string;
  filename?: string;
  origem?: 'sistema' | 'api' | 'coexistencia';
  setor_id?: number;
}

ExternalApiMessageDocumentSendDto

{
  canal_id: number;
  telefone: string;
  legenda?: string;
  file: any;                  // Arquivo enviado via multipart
  origem?: 'sistema' | 'api' | 'coexistencia';
  setor_id?: number;
}

ExternalApiMessageTextTemplateSendDto

{
  canal_id?: number;
  contato_id?: number;
  contato_nome?: string;
  contato_telefone?: string;
  modelo_id: number;          // ID do template
  modelo_variaveis: string[];
  botao_variaveis?: string[];
  media_id?: string;
  status?: 'aberta' | 'encerrada';
  metadata?: string;
  origem?: 'sistema' | 'api' | 'coexistencia';
  setor_id?: number;
}

ExternalApiMessageFlowSendDto

{
  canal_id?: number;
  contato_id?: number;
  contato_telefone?: string;
  contato_nome?: string;
  flow_id: string;            // UUID ou flow_id do Meta
  header_text?: string;
  body_text: string;          // Texto principal
  footer_text?: string;
  cta_text?: string;          // Padrão: "Abrir"
  metadata?: any;
  status?: 'aberta' | 'encerrada';
}

ExternalApiChatTransferDto

{
  setor_id: string | number;
  enviar_mensagem?: boolean | string;
}

ExternalApiChatUpdateDto

{
  tags?: string;              // IDs separados por vírgula
}

ExternalApiFindOrCreateContatoDto

{
  name: string;
  phone: string;
}