API Publica

API publica para integracoes de terceiros e widgets embarcados. Nao requer autenticacao de usuario — usa o identificador do inbox.

Autenticacao

A API publica usa o inbox_identifier no path para identificar o inbox. O contato usa um contact_identifier retornado na criacao.

Contatos

POST/public/api/v1/inboxes/{inbox_identifier}/contacts

Cria um novo contato no inbox publico.

Body

NomeTipoObrigatorioDescricao
namestringNaoNome do contato
emailstringNaoEmail
phone_numberstringNaoTelefone
identifierstringNaoIdentificador externo
custom_attributesobjectNaoAtributos personalizados
bash
curl -X POST "https://chat.seudominio.com/public/api/v1/inboxes/INBOX_IDENTIFIER/contacts" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Visitante do Site",
    "email": "visitante@email.com"
  }'
200Contato criado
json
{
  "source_id": "contact_source_abc123",
  "pubsub_token": "token_for_websocket"
}
GET/public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}

Obtem dados de um contato pelo identificador.

PATCH/public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}

Atualiza dados de um contato publico.

Conversas

POST/public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations

Cria uma nova conversa para o contato.

Body

NomeTipoObrigatorioDescricao
custom_attributesobjectNaoAtributos da conversa
bash
curl -X POST "https://chat.seudominio.com/public/api/v1/inboxes/INBOX_ID/contacts/CONTACT_ID/conversations" \
  -H "Content-Type: application/json" \
  -d '{ "custom_attributes": { "page": "/pricing" } }'
200Conversa criada
json
{
  "id": 999,
  "inbox_id": 1,
  "contact_last_seen_at": "2026-02-15T14:00:00.000Z",
  "status": "open"
}
GET/public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations

Lista as conversas do contato.

Mensagens

POST/public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages

Envia uma mensagem na conversa publica.

Body

NomeTipoObrigatorioDescricao
contentstringSimTexto da mensagem
echo_idstringNaoID local para deduplicacao
bash
curl -X POST "https://chat.seudominio.com/public/api/v1/inboxes/INBOX_ID/contacts/CONTACT_ID/conversations/999/messages" \
  -H "Content-Type: application/json" \
  -d '{ "content": "Preciso de ajuda com meu pedido" }'
GET/public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages

Lista as mensagens da conversa.

PATCH/public/api/v1/inboxes/{inbox_identifier}/contacts/{contact_identifier}/conversations/{conversation_id}/messages/{message_id}

Atualiza uma mensagem (ex: marcar como lida).

Agendamento (Widget Publico)

Endpoint anonimo para o widget de agendamento publico. Nao requer autenticacao. Requer as feature flags appointments_module e appointments_public_widget ativas.

BACK-016 — Identificacao de contato obrigatoria

O objeto contact deve conter phone (ou phone_number) OU email. Se ambos estiverem ausentes, a API retorna 422 com {"errors": {"contact": ["phone or email is required"]}}.

POST/public/api/v1/inboxes/{inbox_identifier}/appointments

Agendamento anonimo via widget publico. Encontra ou cria o contato pelo telefone ou email fornecido.

Path

NomeTipoObrigatorioDescricao
inbox_identifierstringSimIdentificador publico do inbox

Body

NomeTipoObrigatorioDescricao
professional_idintegerSimID do profissional (obtido na listagem publica)
service_idintegerSimID do servico
scheduled_atstring (ISO 8601)SimData/hora do inicio do atendimento (UTC). Deve ser no futuro (BACK-003).
notesstringNaoObservacoes do cliente
contactobjectSimDados de identificacao do contato. Requer phone/phone_number OU email (BACK-016).
contact.namestringNaoNome do contato. Padrao: "Visitante"
contact.phonestringNaoTelefone (E.164 recomendado). Alias: phone_number
contact.emailstringNaoEmail do contato
curl -X POST "https://chat.seudominio.com/public/api/v1/inboxes/INBOX_IDENTIFIER/appointments" \
  -H "Content-Type: application/json" \
  -d '{
    "professional_id": 3,
    "service_id": 7,
    "scheduled_at": "2026-06-15T10:00:00Z",
    "notes": "Primeira consulta",
    "contact": {
      "name": "Maria Silva",
      "phone": "+5511999990000",
      "email": "maria@example.com"
    }
  }'
201Atendimento agendado com sucesso
json
{
  "data": {
    "public_id": "550e8400-e29b-41d4-a716-446655440000",
    "scheduled_at": "2026-06-15T10:00:00.000Z",
    "ends_at": "2026-06-15T11:00:00.000Z",
    "status": "scheduled",
    "professional": { "name": "Dr. Carlos Mendes" },
    "service": { "name": "Limpeza Dental", "duration_minutes": 60 }
  }
}
403Feature nao habilitada
json
{ "error": "feature_not_enabled" }
// ou
{ "error": "public_widget_not_enabled" }
422Erro de validacao
json
// BACK-016 — contato sem phone e sem email:
{ "errors": { "contact": ["phone or email is required"] } }

// BACK-003 — data no passado:
{ "errors": { "scheduled_at": ["must be in the future"] } }

// Conflito de horario:
{ "errors": { "scheduled_at": ["slot already taken"] } }