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/sende 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á um404.
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
filteredirectionsão aplicados a cada página após a leitura, portanto, uma página filtrada pode conter menos itens quelimit. Onext_cursorcontinua avançando pela conversa completa, então continue paginando até quenext_cursorsejanull.
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 deid. 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}/messagescomis_deleted: truee umbodyemedia_urlvazios.
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
hourselimitmoderados 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-flagtambé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.