Autenticação

Toda chamada usa um token de API gerado em Configurações → Integrações, enviado no cabeçalho Authorization. Não existe autenticação por cookie ou sessão nesta API.

  1. Abra Configurações → Integrações e clique em Nova chave.
  2. Escolha um nome e marque os escopos que essa integração vai precisar (veja a tabela abaixo).
  3. Copie o token exibido — ele começa com jc_live_ e não aparece de novo depois. Se perder, revogue a chave e crie outra.
  4. Envie o token em todas as chamadas como Authorization: Bearer <token>.
Requisição
curl https://justchat-api.wpinfotech.com.br/api/v1/external/v1/contacts \
  -H "Authorization: Bearer jc_live_xxxxxxxxxxxxxxxx"
Sem token, ou token inválido → 401
{
  "statusCode": 401,
  "error": "Unauthorized",
  "message": "Token inválido, revogado ou inexistente."
}
O token nunca é reversível. Só é guardado o hash (SHA-256) — a mesma filosofia de nunca armazenar segredo em texto puro que vale para as credenciais de canal. Perdeu o token, revoga e cria outro.

Escopos

Cada chave só acessa o que os escopos marcados na criação permitem. Chamar um endpoint sem o escopo certo devolve 403, não 401 — o token é válido, só não tem essa permissão.

EscopoLibera
contacts:readListar contatos
contacts:writeCriar contatos
conversations:readBuscar uma conversa por id
messages:sendEnviar mensagem em uma conversa
tags:manageListar e criar tags

Contatos

GET/contacts contacts:read

Lista os contatos da empresa, com busca opcional e paginação.

ParâmetroTipoDescrição
searchstring opcionalFiltra por nome, telefone ou e-mail.
pagenumber opcional, padrão 1Página do resultado.
pageSizenumber opcional, padrão 50Itens por página.
Requisição
curl ".../contacts?search=maria&pageSize=10" \
  -H "Authorization: Bearer $TOKEN"
Resposta 200
{
  "data": [{
    "id": "b1ce3253-...",
    "name": "Maria Souza",
    "phone": "5511999998888",
    "email": null,
    "externalId": "5511999998888",
    "customFields": {},
    "optedInAt": "2026-08-01T12:00:00Z"
  }],
  "total": 1, "page": 1, "pageSize": 10
}
POST/contacts contacts:write

Cria um contato. Sem externalId, usa telefone, depois e-mail, depois um id gerado.

CampoTipoDescrição
namestring opcionalNome do contato.
phonestring opcionalTelefone com DDI.
emailstring opcional
externalIdstring opcionalIdentificador único no seu sistema.
customFieldsobject opcionalCampos personalizados já criados em Configurações.
Requisição
curl -X POST .../contacts \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Maria Souza","phone":"5511999998888"}'
Resposta 201
{
  "id": "e421e443-...",
  "name": "Maria Souza",
  "externalId": "5511999998888",
  "phone": "5511999998888",
  "createdAt": "2026-08-28T18:42:46Z"
}
Duplicado: já existe contato com esse externalId400 Bad Request, "Já existe um contato com este identificador".

Conversas

GET/conversations/:id conversations:read

Traz a conversa inteira: contato, canal, time, atendente, tags, agente de IA, todas as mensagens e notas internas.

Requisição
curl .../conversations/7c1a9e2f-... \
  -H "Authorization: Bearer $TOKEN"
Resposta 200 (resumida)
{
  "id": "7c1a9e2f-...",
  "status": "OPEN",
  "protocol": 4821,
  "contact": { "name": "Maria Souza", ... },
  "team": { "id": "...", "name": "Geral" },
  "assignedUser": null,
  "messages": [ /* ordem cronológica */ ]
}

Mensagens

POST/conversations/:id/messages messages:send

Envia uma mensagem de texto na conversa, em nome da integração (aparece com origem API nos relatórios).

CampoTipoDescrição
contentstring obrigatórioTexto da mensagem.
Requisição
curl -X POST .../conversations/7c1a9e2f-.../messages \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content":"Seu pedido foi confirmado."}'
Resposta 400 — janela de 24h fechada
{
  "statusCode": 400,
  "message": "Janela de atendimento de 24h fechada —
  a Meta só aceita template pré-aprovado
  nesta situação."
}
Fora da janela de 24h da Meta (nenhuma mensagem do cliente nas últimas 24h), só um template aprovado pode ser enviado — a mesma regra que vale na tela de atendimento, sem exceção para a API.

Tags

GET/tags tags:manage

Lista as tags (labels) cadastradas na empresa.

Requisição
curl .../tags -H "Authorization: Bearer $TOKEN"
Resposta 200
[
  { "id": "...", "name": "Suporte técnico", "color": "#6366f1" }
]
POST/tags tags:manage

Cria uma tag nova.

CampoTipoDescrição
namestring obrigatório
colorstring opcionalHex, ex: #6366f1.

Webhooks

Cadastrados em Configurações → Integrações — o JustChat faz um POST na sua URL a cada evento assinado. Só os eventos abaixo existem hoje; nenhum outro é prometido.

message.received

Uma mensagem chegou de um contato.

conversation.created

Uma conversa nova foi aberta.

conversation.resolved

Uma conversa foi marcada como resolvida.

contact.created

Um contato novo foi cadastrado.

Corpo da entrega
{
  "event": "contact.created",
  "data": {
    "contact": {
      "id": "ed59657c-...",
      "name": "Maria Souza",
      "phone": "5511988887777",
      "email": null,
      "externalId": "5511988887777"
    }
  }
}

Cabeçalhos enviados em toda entrega:

X-JustChat-EventNome do evento, igual ao campo event do corpo.
X-JustChat-SignatureHMAC-SHA256 do corpo (hex), assinado com o segredo mostrado na criação do webhook.
Verificando a assinatura (Node.js)
const crypto = require("crypto");

const esperada = crypto
  .createHmac("sha256", WEBHOOK_SECRET)
  .update(corpoCru) // string exata do corpo recebido
  .digest("hex");

if (esperada !== headers["x-justchat-signature"]) {
  // rejeita — a chamada não veio do JustChat
}
Reentrega automática: se seu endpoint não responder 2xx, o JustChat tenta de novo até 5 vezes, com espera crescente (5s, 10s, 20s...). Toda tentativa — sucesso ou falha — fica no log de entregas da tela, com status HTTP e horário.

Códigos de erro

401
Sem token ou token inválido/revogado.

Confira o cabeçalho Authorization: Bearer <token> — sem ele a mensagem é "Faltou o header...", com token errado é "Token inválido, revogado ou inexistente."

403
Token válido, sem o escopo exigido.

A mensagem cita o escopo que falta, ex.: "Esta chave não tem o escopo 'messages:send'."

400
Corpo inválido ou regra de negócio.

Ex.: contato duplicado, mensagem sem conteúdo, ou janela de 24h fechada sem template.

404
Recurso não encontrado nesta empresa.

O token só enxerga dados da própria empresa — um id de outra conta responde 404, nunca 403.