Your AI Connector Docs

Mensagens e Conversas

A API de Mensagens permite que você envie uma mensagem para qualquer contato, leia uma conversa, corrija ou remova uma mensagem que você já enviou, reaja a uma, puxe um tópico completo de sessão de chat, exporte uma transcrição e marque chats como lidos ou não lidos — tudo sem abrir a caixa de entrada.

Todos os caminhos nesta página são relativos à URL base https://api.youraiconnector.com/v1. Cada solicitação precisa da sua chave de API — consulte Autenticação para obter a lista completa de formas de enviá-la. Os exemplos abaixo usam o cabeçalho X-API-Key, com um exemplo cURL mostrando também o formato de consulta ?apiKey=.

Como funciona a entrega: O envio de uma mensagem não aguarda que ela chegue ao destino. A API aceita sua mensagem, retorna imediatamente com um ID de mensagem e, em seguida, a entrega em segundo plano no canal do contato (WhatsApp, SMS, Instagram, etc.). Para rastrear se uma mensagem foi realmente entregue ou lida, escute as atualizações de status com Webhooks — não faça polling. A resposta de envio apenas confirma que a mensagem foi aceita.


Enviar uma mensagem

Existem duas maneiras de enviar. Escolha a que melhor se adapta à forma como você já identifica o contato:

  • Enviar por ID de contato — você já conhece o ID do contato (por exemplo, você criou o contato através da API ou o obteve de um webhook). Use POST /contacts/{contactId}/send-message.
  • Enviar por identidade do contato — você conhece o número de telefone do contato, ID do Instagram, etc., mas não o ID interno dele. Use POST /contacts/send e deixe a plataforma encontrar o contato correto.

Ambos enfileiram a mensagem da mesma forma e a entregam no canal em que o contato estiver. Você não escolhe um transporte — a plataforma roteia contatos do WhatsApp via WhatsApp, contatos de SMS via SMS, e assim por diante.

Enviar por ID de contato

POST /contacts/{contactId}/send-message

Campo Obrigatório Descrição
body Sim O texto da mensagem a ser enviada.
mediaUrl Não URL de um arquivo de mídia (imagem, documento, etc.) para anexar.
mediaContentType Não Tipo MIME da mídia anexada, por exemplo, image/jpeg.
pauseBot Não true pausa a IA para este contato conforme a mensagem é enviada — para quando um humano assume o atendimento. Veja Pausar ou retomar a IA.
clearIncompleteReply Não true descarta uma resposta do bot inacabada para que ela não seja retomada após sua mensagem.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi! Your appointment is confirmed for tomorrow at 10:00."
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      body: "Hi! Your appointment is confirmed for tomorrow at 10:00.",
    }),
  }
);
const data = await res.json();
console.log(data.messageId);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/send-message",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Hi! Your appointment is confirmed for tomorrow at 10:00."},
)
print(res.json()["messageId"])

Resposta (200 OK):

{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}

Enviar por identidade do contato

POST /contacts/send

Use isto quando você não tiver o ID interno do contato. Forneça o body da mensagem mais ou um contact_id, ou um channel junto com o campo de identidade que corresponde a esse canal.

Campo Obrigatório Descrição
body Sim O texto da mensagem a ser enviada.
contact_id Não ID de um contato existente. Quando definido, os campos de identidade abaixo não são necessários.
channel Não Canal para envio. Obrigatório quando contact_id não é fornecido. Um dos 14 canais de envio de saída: whatsapp, whatsapp_web, sms, instagram, instagram_private, messenger, telegram, chat-widget, custom, email, line, imessage, linkedin, viber.
phone_number Não Número de telefone do contato no formato internacional. Usado com whatsapp, whatsapp_web e sms.
instagram_id Não ID de usuário do Instagram do contato. Usado com instagram.
messenger_id Não ID de usuário do Messenger do contato. Usado com messenger.
telegram_user_id Não ID de usuário do Telegram do contato. Usado com telegram.
media_url Não URL de um arquivo de mídia para anexar.
media_content_type Não Tipo MIME da mídia anexada, por exemplo, image/jpeg.

Quais canais podem ser resolvidos por identidade. Apenas seis dos 14 aceitam um campo de identidade em vez de um contact_id: whatsapp, whatsapp_web e sms são pesquisados por phone_number, instagram por instagram_id, messenger por messenger_id, e telegram por telegram_user_id. Os outros oito — instagram_private, chat-widget, custom, email, line, imessage, linkedin e viber — não possuem identidade pública para pesquisa, portanto, enviar por esses canais requer contact_id; passar apenas channel retorna um 400 informando que contact_id é necessário.

cURL (usando o formato de consulta ?apiKey=)

curl -X POST "https://api.youraiconnector.com/v1/contacts/send?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "phone_number": "+31612345678",
    "body": "Hi! Your appointment is confirmed."
  }'

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/contacts/send", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    channel: "whatsapp",
    phone_number: "+31612345678",
    body: "Hi! Your appointment is confirmed.",
  }),
});
const data = await res.json();
console.log(data.message_id, data.channel);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/send",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "channel": "whatsapp",
        "phone_number": "+31612345678",
        "body": "Hi! Your appointment is confirmed.",
    },
)
data = res.json()
print(data["message_id"], data["channel"])

Resposta (201 Created):

{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp"
}

Por que uma mensagem pode ser rejeitada: Um contato com o modo “não perturbe” ou modo privado ativado não pode receber mensagens de saída — a solicitação falha com um 422. Se nenhum contato corresponder ao ID ou identidade que você forneceu, você receberá um 404.


Listar mensagens de um contato

GET /contacts/{contactId}/messages

Retorna as mensagens de um contato, da mais recente para a mais antiga, com paginação baseada em cursor.

Parâmetro de consulta Obrigatório Descrição
limit Não Tamanho da página. Padrão 50, máximo 100.
cursor Não O valor next_cursor de uma resposta anterior. Retorna mensagens mais antigas que o cursor.
filter Não Filtrar por tipo de conteúdo: all (padrão), text, media ou tool_use.
direction Não Filtrar por direção: all (padrão), inbound (recebido do contato) ou outbound (enviado por você).

Nota sobre filtragem e paginação: Os filtros filter e direction são aplicados a cada página após a leitura, portanto, uma página filtrada pode conter menos itens que limit. O next_cursor continua avançando pela conversa completa, então continue paginando até que next_cursor seja null.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&direction=inbound" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ limit: "50", direction: "inbound" });
const res = await fetch(
  `https://api.youraiconnector.com/v1/contacts/contact123/messages?${params}`,
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.messages, data.next_cursor);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"limit": 50, "direction": "inbound"},
)
data = res.json()
print(data["messages"], data["next_cursor"])

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T10:00:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ],
  "next_cursor": "cD4eF6gH8iJ0kL2mN3oP"
}

Campos da mensagem

Campo Descrição
id ID exclusivo da mensagem.
body Conteúdo de texto da mensagem.
direction inbound (recebida do contato) ou outbound (enviada pela sua conta).
channel Canal no qual a mensagem foi enviada ou recebida (por exemplo, whatsapp, sms, instagram).
status Status de entrega atual, por exemplo, Created, sent, delivered, read, failed.
type Tipo de mensagem. Mensagens de texto simples têm um tipo null; a atividade da ferramenta de assistente automatizado é marcada como tool_use.
timestamp Hora ISO 8601 em que a mensagem foi criada.
media_url URL de um arquivo de mídia anexado, se houver.
media_content_type Tipo MIME da mídia anexada, se houver.
bot_reply true quando a mensagem foi gerada pelo assistente de IA.
score Sua avaliação da mensagem: 1 polegar para cima, -1 polegar para baixo, 0 quando não foi avaliada. Veja Avaliar ou marcar uma mensagem com estrela.
is_important true quando a mensagem foi marcada com estrela.
is_deleted true quando a mensagem foi excluída. Mensagens excluídas permanecem na lista, mas seus body e media_url ficam vazios.
reactions Reações com emoji na mensagem, de ambos os lados. Sempre um array — vazio quando não há nenhuma. Cada entrada tem emoji, from_phone_number, from_me (true quando a reação é sua) e reacted_at.

Listar sessões de chat

Uma sessão de chat é uma janela de conversa com um contato: ela abre quando eles começam a falar e fecha quando a conversa é concluída. As sessões são a forma como você pagina um longo histórico em conversas legíveis, em vez de uma lista interminável.

Sessões recentes de todos os contatos

GET /chat-sessions/recent

Retorna as sessões que começaram nas últimas X horas, da mais recente para a mais antiga, em todos os contatos da conta.

Parâmetro de consulta Obrigatório Descrição
hours Sim Quantas horas retroceder. Deve ser um número inteiro positivo.
status Não Retornar apenas sessões com este status: ChatSessionOpened ou ChatSessionClosed.
limit Não Número máximo de sessões a retornar. Padrão 100, máximo 100.
includeMessages Não true adiciona um array messages a cada sessão. Desativado por padrão porque torna a resposta muito maior.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/recent?hours=24&status=ChatSessionClosed" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const params = new URLSearchParams({ hours: "24", status: "ChatSessionClosed" });
const res = await fetch(`https://api.youraiconnector.com/v1/chat-sessions/recent?${params}`, {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.data.total_sessions, data.data.sessions);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-sessions/recent",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"hours": 24, "status": "ChatSessionClosed"},
)
data = res.json()["data"]
print(data["total_sessions"], data["sessions"])

Resposta (200 OK):

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_sessions": 2,
    "sessions": [
      {
        "session_id": "session456",
        "contact_id": "contact123",
        "contact_name": "Jane Doe",
        "contact_phone": "+31612345678",
        "contact_email": "jane@example.com",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Todas as sessões de um contato

GET /chat-sessions/{contactId}

Retorna todas as sessões de chat de um único contato. Mesmos parâmetros status, limit e includeMessages acima — hours não se aplica aqui.

cURL

curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
  -H "X-API-Key: YOUR_API_KEY"

Resposta (200 OK):

{
  "success": true,
  "data": {
    "contact_id": "contact123",
    "contact_name": "Jane Doe",
    "total_sessions": 2,
    "sessions": [
      {
        "id": "session456",
        "start_date_time": "2026-06-01T09:55:00.000Z",
        "end_date_time": "2026-06-01T10:20:00.000Z",
        "status": "ChatSessionClosed",
        "tag": "Booking enquiry"
      }
    ]
  }
}

Os nomes dos campos de ID da sessão diferem entre os dois endpoints. A lista de sessões recentes chama-o de session_id (também contém os detalhes do contato, já que as sessões vêm de muitos contatos); a lista por contato chama-o de id. Qualquer um dos valores é o que você passa como {sessionId} ao buscar o tópico completo abaixo.

Quando includeMessages=true, cada sessão ganha um array messages cujas entradas contêm id, body, direction, timestamp, type, channel e status.


Buscar um thread de sessão de chat

GET /contacts/{contactId}/chat-sessions/{sessionId}/messages

Uma sessão de chat agrupa as mensagens de um contato em uma única janela de conversa. Este endpoint retorna o tópico completo de uma única sessão, do mais antigo para o mais recente, juntamente com os metadados da sessão. Você pode encontrar os IDs de sessão de um contato através dos endpoints de sessões de chat.

cURL

curl "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.session, data.messages);

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts/contact123/chat-sessions/session456/messages",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["session"], data["messages"])

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "session": {
    "id": "session456",
    "status": "ChatSessionClosed",
    "start_date_time": "2026-06-01T09:55:00.000Z",
    "end_date_time": "2026-06-01T10:20:00.000Z",
    "tag": "Booking enquiry"
  },
  "messages": [
    {
      "id": "aB3dE5fG7hI9jK1lM2nO",
      "body": "Hi! Thanks for reaching out.",
      "direction": "inbound",
      "channel": "whatsapp",
      "status": "delivered",
      "type": null,
      "timestamp": "2026-06-01T09:55:00.000Z",
      "media_url": null,
      "media_content_type": null,
      "bot_reply": false
    }
  ]
}

O objeto session informa status (ChatSessionOpened enquanto ativo, ChatSessionClosed após encerrado), start_date_time, end_date_time e um tag legível por humanos. O array messages usa os mesmos campos de mensagem que o endpoint de listagem.


Editar, excluir e reagir a mensagens

Esses endpoints alteram uma mensagem após ela ter sido enviada. Dois deles alcançam o canal do contato, bem como sua própria cópia, portanto, leia a introdução da seção antes de configurá-los — o que é possível depende inteiramente do canal em que a conversa está ocorrendo.

O que cada canal permite

Ação Canais que podem alterar a cópia do contato Limite de tempo
Editar uma mensagem enviada Widget de chat, WhatsApp Web, Telegram, LinkedIn Nenhum no widget de chat, 15 minutos no WhatsApp Web, 48 horas no Telegram, 60 minutos no LinkedIn
Excluir para todos Widget de chat, WhatsApp Web, Telegram, LinkedIn 60 minutos no LinkedIn; os outros não possuem limite publicado
Reagir com um emoji WhatsApp Web, Telegram Nenhum

Em todos os outros canais — a API do WhatsApp Business, SMS, Instagram, Messenger, e-mail, LINE, canais personalizados — uma exclusão ainda remove a mensagem da sua caixa de entrada, mas o contato mantém a cópia dele, e editar ou reagir não é possível de forma alguma.

Editar uma mensagem

POST /contacts/{contactId}/messages/{messageId}/edit

Reescreve uma mensagem que você já enviou, no dispositivo do contato e na sua cópia.

Campo Obrigatório Descrição
body Sim O novo texto da mensagem. Não deve estar vazio e pode ter no máximo 4096 caracteres.

Ao contrário da exclusão, isso falha de forma explícita quando o canal recusa: você recebe um 409 e sua cópia é deixada exatamente como a do contato, porque mostrar uma edição que eles nunca receberam deixaria os dois lados desalinhados. O campo edit_reason informa o motivo — a janela de edição do canal expirou, o canal está desconectado ou algo deu errado.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Sorry - I meant Thursday at 3pm." }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ body: "Sorry - I meant Thursday at 3pm." }),
  }
);
const data = await res.json();
console.log(data.edited, data.edit_reason);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/edit",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"body": "Sorry - I meant Thursday at 3pm."},
)
data = res.json()
print(data.get("edited"), data.get("edit_reason"))

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "edited": true,
  "edit_reason": "edit_dispatched"
}

Se o canal não aceitar a edição, você recebe um 409 em vez disso, e nada foi alterado:

{
  "success": false,
  "error": "The message could not be edited",
  "edit_reason": "channel_disconnected"
}

Uma mensagem que já foi excluída, um canal que não permite edição de forma alguma e uma mensagem que é muito antiga para seu canal retornam 400 — a solicitação nunca chega ao canal.

Excluir uma mensagem

DELETE /contacts/{contactId}/messages/{messageId}

Remove a mensagem da sua conversa e, onde o canal permite, retira a cópia do contato também. Sem corpo de solicitação.

Isso sempre responde 200 quando a mensagem existia, mesmo que a cópia do contato não pudesse ser retraída — sua cópia foi removida, então um erro seria enganoso. Leia os três campos na resposta para informar ao usuário o que realmente aconteceu:

Campo Descrição
revoke_supported Se este canal pode retrair mensagens.
revoked Se a cópia no dispositivo do contato foi removida.
revoke_reason Por que não foi removida, quando revoked é false — por exemplo revoke_window_closed ou already_deleted.

cURL

curl -X DELETE "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.revoked, data.revoke_reason);

Python

import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["revoked"], data["revoke_reason"])

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "revoke_supported": true,
  "revoked": true,
  "revoke_reason": "revoke_dispatched"
}

As mensagens excluídas não são removidas do histórico da conversa. Elas permanecem em GET /contacts/{contactId}/messages com is_deleted: true e um body e media_url vazios.

Excluir várias mensagens de uma vez

POST /contacts/{contactId}/messages/bulk-delete

Limpa um lote de mensagens apenas do seu lado. Os corpos e anexos são esvaziados, mas nada é retraído no dispositivo do contato — para também retirar uma mensagem, exclua-a uma por uma com o endpoint de mensagem única acima.

Campo Obrigatório Descrição
message_ids Sim Uma matriz não vazia de IDs de mensagem, até 500 por solicitação. messageIds é aceito como um alias.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "message_ids": ["msg_1", "msg_2"] }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ message_ids: ["msg_1", "msg_2"] }),
  }
);
console.log((await res.json()).deleted);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/bulk-delete",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["msg_1", "msg_2"]},
)
print(res.json()["deleted"])

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "deleted": 2
}

Reagir a uma mensagem

POST /contacts/{contactId}/messages/{messageId}/react

Coloca sua própria reação de emoji em uma mensagem, ou a retira enviando uma string vazia. As reações do próprio contato nunca são alteradas.

Campo Obrigatório Descrição
emoji Sim O emoji para reagir, ou "" para remover sua reação. Deve ser uma única string sem espaços, com no máximo 16 caracteres.

Assim como a edição, isso falha em vez de mostrar uma reação que o contato nunca recebeu, e a falha informa se vale a pena tentar novamente:

  • 422 — nunca poderá ser entregue nesta conversa: o canal não suporta reações, a mensagem não tem um ID do lado do canal ou o emoji está fora do conjunto permitido pelo canal.
  • 409 — o canal estava momentaneamente inacessível. Uma nova tentativa pode funcionar.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "emoji": "👍" }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ emoji: "👍" }),
  }
);
const data = await res.json();
console.log(data.reactions);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1/react",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"emoji": "👍"},
)
print(res.json()["reactions"])

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "reaction_supported": true,
  "reaction_reason": "reaction_dispatched",
  "reactions": [
    {
      "emoji": "👍",
      "from_phone_number": "+31612345678",
      "from_me": true,
      "reacted_at": "2026-06-01T10:05:00.000Z"
    }
  ]
}

A matriz reactions é o conjunto completo de reações agora na mensagem, as suas e as do contato. Em um 409 ou 422, ela é retornada inalterada, portanto, um cliente que renderiza diretamente a partir dela nunca mostra uma reação que não foi entregue.

Avaliar ou marcar uma mensagem com estrela

PATCH /contacts/{contactId}/messages/{messageId}

Avalia uma mensagem com polegar para cima ou para baixo e/ou marca-a como importante. Isso é um controle apenas do seu lado — nada é enviado ao contato.

Campo Obrigatório Descrição
score Não 1 curtir, -1 descurtir, 0 limpa a avaliação.
is_important Não true marca a mensagem com estrela, false remove a estrela. Deve ser um booleano real, não a string "true".

Envie pelo menos um dos dois, ou você receberá um 400. Apenas o que você envia é gravado, portanto, marcar uma mensagem com estrela nunca limpa sua avaliação e vice-versa — e a resposta ecoa apenas os campos que você enviou.

cURL

curl -X PATCH "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "score": 1, "is_important": true }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1", {
  method: "PATCH",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ score: 1, is_important: true }),
});

Python

import requests

requests.patch(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/msg_1",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"score": 1, "is_important": True},
)

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "message_id": "msg_1",
  "score": 1,
  "is_important": true
}

Marcar mensagens como lidas

Você pode limpar o status de não lido para mensagens específicas ou para toda a conversa.

Marcar mensagens específicas como lidas

POST /contacts/{contactId}/messages/mark-read

Passe os IDs das mensagens a serem marcadas como lidas.

Campo Obrigatório Descrição
message_ids Sim Um array não vazio de IDs de mensagem (até 500 por solicitação).

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]
  }'

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      message_ids: ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"],
    }),
  }
);
const data = await res.json();
console.log(data.marked_read);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/messages/mark-read",
    headers={
        "X-API-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={"message_ids": ["aB3dE5fG7hI9jK1lM2nO", "cD4eF6gH8iJ0kL2mN3oP"]},
)
print(res.json()["marked_read"])

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123",
  "marked_read": 2
}

Marcar todo o chat como lido

POST /contacts/{contactId}/mark-read

Limpa o selo de não lido de toda a conversa do contato na caixa de entrada. Nenhum corpo de solicitação é necessário.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-read" \
  -H "X-API-Key: YOUR_API_KEY"

JavaScript

const res = await fetch(
  "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.success);

Python

import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/contacts/contact123/mark-read",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123"
}

Marcar toda a conversa como não lida

POST /contacts/{contactId}/mark-unread

Coloca o selo de não lida de volta na conversa — útil quando alguém da sua equipe abriu um chat, mas está passando a tarefa adiante. Nenhum corpo de requisição é necessário.

Esta é uma flag exclusiva da caixa de entrada: ela não altera quando a conversa foi lida pela última vez, portanto, nenhum recibo de leitura é enviado ao contato em canais que oferecem suporte a eles.

cURL

curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
  -H "X-API-Key: YOUR_API_KEY"

Resposta (200 OK):

{
  "success": true,
  "contact_id": "contact123"
}

Exportar uma conversa

As exportações fornecem uma conversa inteira como uma transcrição legível, em vez de navegar pelas mensagens página por página. Cada endpoint de exportação aceita um filter de all (padrão), text, media ou tool_use, correspondendo ao filtro na lista de mensagens.

Exportar o chat de um contato

GET /chat-exports/{contactId}

Parâmetro de consulta Obrigatório Descrição
format Não txt (padrão) retorna um link de download para uma transcrição em texto simples. json retorna as mensagens como dados estruturados na resposta.
filter Não all (padrão), text, media ou tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/contact123?format=json" \
  -H "X-API-Key: YOUR_API_KEY"

Python

import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/chat-exports/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"format": "json"},
)
print(res.json()["data"]["messages"])

Resposta com format=json (200 OK):

{
  "success": true,
  "data": {
    "contact": {
      "id": "contact123",
      "name": "Jane Doe",
      "phone": "+31612345678",
      "email": "jane@example.com"
    },
    "messages": [
      {
        "body": "Hi! I have a question about my order.",
        "direction": "inbound",
        "timestamp": "2026-06-01T09:55:00.000Z",
        "type": "text",
        "media_url": null,
        "media_content_type": null,
        "name": null,
        "args": null
      }
    ]
  }
}

Com format=txt (o padrão), data é, em vez disso, um link de download para o arquivo de transcrição gerado:

{
  "success": true,
  "data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}

O link de download tem curta duração. Busque o arquivo assim que receber o link, em vez de armazená-lo — solicite uma nova exportação quando precisar da transcrição novamente.

Exportar todas as conversas recentes

GET /chat-exports/recent

Exporta as conversas de todos os contatos que estiveram ativos nas últimas X horas, em uma única chamada.

Parâmetro de consulta Obrigatório Descrição
hours Sim Quantas horas de atividade considerar. Deve ser um número inteiro positivo.
format Não json (padrão) retorna uma entrada por contato. txt retorna um único arquivo de texto para download com todas as conversas.
limit Não Número máximo de contatos para exportar. Padrão 50, máximo 100.
filter Não all (padrão), text, media ou tool_use.

cURL

curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
  -H "X-API-Key: YOUR_API_KEY"

Resposta (200 OK):

{
  "success": true,
  "data": {
    "hours_ago": 24,
    "total_contacts": 2,
    "exports": [
      {
        "contactId": "contact123",
        "contactName": "Jane Doe",
        "phoneNumber": "+31612345678",
        "email": "jane@example.com",
        "messageCount": 12,
        "chatExport": "Acme Export - Jane Doe\nPhone: +31612345678\n..."
      }
    ]
  }
}

Com format=txt, a resposta é o próprio arquivo de texto, enviado como um download em vez de JSON.

Esta chamada única extrai o histórico completo de cada contato correspondente, portanto, mantenha hours e limit moderados em contas com muito movimento.

Enviar uma transcrição por e-mail para o contato

POST /chat-exports/{contactId}/email

Envia ao contato a sua própria transcrição da conversa por e-mail — o fluxo “enviar este chat por e-mail”, acionado a partir do seu próprio sistema.

Campo Obrigatório Descrição
recipient_email Não Para onde enviar. O padrão é o endereço de e-mail armazenado do contato.
via Não auto (padrão) escolhe a melhor rota, transactional envia como um e-mail do sistema, email_channel envia a partir do seu canal de e-mail conectado.
note Não Uma breve linha sua exibida acima da transcrição. Até 1000 caracteres.

cURL

curl -X POST "https://api.youraiconnector.com/v1/chat-exports/contact123/email" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Here is a copy of our chat, as promised." }'

Resposta (200 OK):

{
  "success": true,
  "data": {
    "via": "transactional",
    "recipientEmail": "jane@example.com",
    "messageCount": 42,
    "omittedCount": 0
  }
}

omittedCount informa quantas das mensagens mais antigas foram omitidas para manter o e-mail com um tamanho razoável. Um 200 significa que a transcrição foi criada e colocada na fila para envio, não que ela já chegou à caixa de entrada.


Pausar ou retomar a IA para um contato

PUT /contacts/{contactId}

Defina is_bot_active como false para impedir que a IA responda a um contato, e volte para true para devolver a conversa. Este é o interruptor de controle que você deseja quando um humano assume uma conversa: as mensagens enviadas por você com a API ainda são entregues enquanto o bot está pausado.

cURL

curl -X PUT "https://api.youraiconnector.com/v1/contacts/contact123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_bot_active": false }'

JavaScript

await fetch("https://api.youraiconnector.com/v1/contacts/contact123", {
  method: "PUT",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ is_bot_active: false }),
});

Python

import requests

requests.put(
    "https://api.youraiconnector.com/v1/contacts/contact123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"is_bot_active": False},
)

Resposta

{
  "success": true,
  "contact_id": "contact123"
}

Pausando como parte da resposta

Se um humano estiver assumindo o atendimento ao enviar uma resposta, você pode pausar o bot na mesma solicitação em vez de fazer uma segunda chamada. POST /contacts/{contactId}/send-message aceita duas flags opcionais:

Campo Descrição
pauseBot true pausa a IA para este contato conforme a mensagem é enviada.
clearIncompleteReply true descarta uma resposta do bot inacabada para que ela não seja retomada posteriormente.
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/send-message" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Hi, Sarah here - taking over from the assistant.",
    "pauseBot": true,
    "clearIncompleteReply": true
  }'

A resposta inclui "botPaused": true quando a pausa foi aplicada.

Marcar um contato como privado com POST /contacts/bulk-flag também pausa o bot para ele. Veja Contatos para a lista completa de campos.


Construindo sua própria caixa de entrada

Tudo o que uma caixa de entrada precisa está nesta página e em Contatos:

O que você precisa Endpoint
Listar conversas GET /contacts
Ler uma conversa GET /contacts/{contactId}/messages
Listar sessões de chat de um contato GET /chat-sessions/{contactId}
Ver o que chegou recentemente GET /chat-sessions/recent
Ler uma sessão de chat GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Enviar uma resposta manual POST /contacts/{contactId}/send-message
Corrigir uma resposta que você acabou de enviar POST /contacts/{contactId}/messages/{messageId}/edit
Remover uma mensagem DELETE /contacts/{contactId}/messages/{messageId}
Limpar várias mensagens POST /contacts/{contactId}/messages/bulk-delete
Reagir com um emoji POST /contacts/{contactId}/messages/{messageId}/react
Avaliar ou marcar uma mensagem com estrela PATCH /contacts/{contactId}/messages/{messageId}
Marcar como lida POST /contacts/{contactId}/mark-read
Devolver um chat para a equipe POST /contacts/{contactId}/mark-unread
Exportar uma transcrição GET /chat-exports/{contactId}
Pausar ou retomar a IA PUT /contacts/{contactId} com is_bot_active

Para atualizações em tempo real, inscreva-se nos eventos New Message, Replies, Human Alerted e Chat Concluded com Webhooks em vez de consultar esta API periodicamente.


Erros da API de Mensagens

Os endpoints de mensagem retornam o envelope de erro padrão:

{
  "success": false,
  "error": "Contact not found"
}
Status Quando ocorre em um endpoint de mensagem
400 Um campo obrigatório está faltando ou um parâmetro é inválido (bad limit, hours, filter, direction, status, um array message_ids vazio ou com mais de 500 itens, um cursor inválido, uma edição body vazia ou longa demais, um score fora de -1/0/1, ou um emoji com espaços ou mais de 16 caracteres). Também retornado quando uma mensagem não pode ser editada de forma alguma — ela foi excluída, seu canal não permite edição ou está fora da janela de edição daquele canal.
404 O contato, a sessão de chat ou um dos IDs de mensagem fornecidos não foi encontrado.
409 O canal não aceita a alteração no momento. Nada foi gravado: em uma edição, edit_reason diz o motivo; em uma reação, o canal estava momentaneamente inacessível e uma nova tentativa pode funcionar.
422 O contato não pode receber mensagens de saída (não perturbe, privado ou um canal não suportado), ou uma reação nunca pode ser entregue nesta conversa (reaction_reason diz qual).

Os códigos compartilhados que todo endpoint pode retornar — 401, 403 (seu plano não inclui acesso à API), 429 (limite de taxa) e 500 — estão listados com orientações de nova tentativa em Erros e Paginação.


Próximos passos

  • Webhooks — receba atualizações de status de entrega em vez de fazer polling.
  • Contatos — crie e pesquise os contatos para os quais você envia mensagens.
  • Agendamentos — reserve e gerencie agendamentos para seus contatos.