Mensagens e Conversas
A API de Mensagens permite-lhe enviar uma mensagem a qualquer contacto, ler uma conversa, corrigir ou remover uma mensagem que já enviou, reagir a uma, obter um tópico completo de sessão de chat, exportar uma transcrição e marcar conversas como lidas ou não lidas — tudo isto sem abrir a caixa de entrada.
Todos os caminhos nesta página são relativos ao URL base https://api.youraiconnector.com/v1. Cada pedido necessita da sua chave de API — consulte Autenticação para obter a lista completa de formas de a enviar. Os exemplos abaixo utilizam o cabeçalho X-API-Key, com um exemplo cURL que mostra também o formulário de consulta ?apiKey=.
Como funciona a entrega: O envio de uma mensagem não aguarda pela sua chegada. A API aceita a sua mensagem, responde imediatamente com um ID de mensagem e, em seguida, entrega-a em segundo plano no canal do contacto (WhatsApp, SMS, Instagram, etc.). Para verificar se uma mensagem foi efetivamente entregue ou lida, utilize Webhooks para receber atualizações de estado — não utilize polling. A resposta de envio apenas confirma que a mensagem foi aceite.
Enviar uma mensagem
Existem duas formas de enviar. Escolha a que melhor se adapta à forma como já identifica o contacto:
- Enviar por ID de contacto — já conhece o ID do contacto (por exemplo, criou o contacto através da API ou obteve-o a partir de um webhook). Utilize
POST /contacts/{contactId}/send-message. - Enviar por identidade de contacto — conhece o número de telefone, ID de Instagram, etc., do contacto, mas não o seu ID interno. Utilize
POST /contacts/sende deixe que a plataforma encontre o contacto correto.
Ambos colocam a mensagem na fila da mesma forma e entregam-na no canal em que o contacto se encontra. Não escolhe um transporte — a plataforma encaminha os contactos de WhatsApp via WhatsApp, os contactos de SMS via SMS, e assim sucessivamente.
Enviar por ID de contacto
POST /contacts/{contactId}/send-message
| Campo | Obrigatório | Descrição |
|---|---|---|
body |
Sim | O texto da mensagem a enviar. |
mediaUrl |
Não | URL de um ficheiro de multimédia (imagem, documento, etc.) a anexar. |
mediaContentType |
Não | Tipo MIME do ficheiro multimédia anexado, p. ex. image/jpeg. |
pauseBot |
Não | true suspende a IA para este contacto à medida que a mensagem é enviada — para uma intervenção humana. Consulte Suspender ou retomar a IA. |
clearIncompleteReply |
Não | true descarta uma resposta do bot incompleta para que esta não seja retomada após a 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 de contacto
POST /contacts/send
Utilize isto quando não tiver o ID interno do contacto. Forneça o body da mensagem mais ou um contact_id, ou um channel juntamente com o campo de identidade que corresponde a esse canal.
| Campo | Obrigatório | Descrição |
|---|---|---|
body |
Sim | O texto da mensagem a enviar. |
contact_id |
Não | ID de um contacto existente. Quando definido, os campos de identidade abaixo não são necessários. |
channel |
Não | Canal através do qual enviar. 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 contacto em formato internacional. Utilizado com whatsapp, whatsapp_web e sms. |
instagram_id |
Não | ID de utilizador do Instagram do contacto. Utilizado com instagram. |
messenger_id |
Não | ID de utilizador do Messenger do contacto. Utilizado com messenger. |
telegram_user_id |
Não | ID de utilizador do Telegram do contacto. Utilizado com telegram. |
media_url |
Não | URL de um ficheiro multimédia a anexar. |
media_content_type |
Não | Tipo MIME do ficheiro multimédia anexado, por exemplo, image/jpeg. |
Que 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 têm identidade pública para pesquisa, pelo que o envio através desses canais requer contact_id; passar apenas channel devolve um 400 a indicar que contact_id é necessário.
cURL (utilizando o formulário 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 motivo uma mensagem pode ser rejeitada: Um contacto com o modo “não incomodar” ou modo privado ativado não pode receber mensagens de saída — o pedido falha com um
422. Se nenhum contacto corresponder ao ID ou identidade que forneceu, receberá um404.
Listar as mensagens de um contacto
GET /contacts/{contactId}/messages
Devolve as mensagens de um contacto, 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. Predefinição 50, máximo 100. |
cursor |
Não | O valor next_cursor de uma resposta anterior. Devolve mensagens mais antigas do que o cursor. |
filter |
Não | Filtrar por tipo de conteúdo: all (predefinição), text, media ou tool_use. |
direction |
Não | Filtrar por direção: all (predefinição), inbound (recebida do contacto) ou outbound (enviada por si). |
Nota sobre filtragem e paginação: Os filtros
filteredirectionsão aplicados a cada página após a sua leitura, pelo que uma página filtrada pode conter menos itens do quelimit. Onext_cursorcontinua a avançar pela conversa completa, por isso continue a paginar 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 único da mensagem. |
body |
Conteúdo de texto da mensagem. |
direction |
inbound (recebida do contacto) ou outbound (enviada pela sua conta). |
channel |
Canal através do qual a mensagem foi enviada ou recebida (por exemplo, whatsapp, sms, instagram). |
status |
Estado de entrega atual, por exemplo, Created, sent, delivered, read, failed. |
type |
Tipo de mensagem. As 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 ficheiro multimédia em anexo, se existir. |
media_content_type |
Tipo MIME do multimédia em anexo, se existir. |
bot_reply |
true quando a mensagem foi gerada pelo assistente de IA. |
score |
A sua classificação da mensagem: 1 polegar para cima, -1 polegar para baixo, 0 quando não foi classificada. Consulte Classificar ou marcar uma mensagem com estrela. |
is_important |
true quando a mensagem foi marcada com estrela. |
is_deleted |
true quando a mensagem foi eliminada. As mensagens eliminadas permanecem na lista, mas o seu body e media_url estão vazios. |
reactions |
Reações com emoji na mensagem, de ambos os lados. É sempre uma matriz — vazia quando não existem. 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 contacto: abre-se quando este começa a falar e fecha-se quando a conversa termina. As sessões são a forma de dividir um histórico longo em conversas legíveis, em vez de uma lista interminável.
Sessões recentes de todos os contactos
GET /chat-sessions/recent
Devolve as sessões iniciadas nas últimas X horas, da mais recente para a mais antiga, de todos os contactos na conta.
| Parâmetro de consulta | Obrigatório | Descrição |
|---|---|---|
hours |
Sim | Quantas horas retroceder. Deve ser um número inteiro positivo. |
status |
Não | Devolver apenas sessões com este estado: ChatSessionOpened ou ChatSessionClosed. |
limit |
Não | Número máximo de sessões a devolver. O padrão é 100, o máximo é 100. |
includeMessages |
Não | true adiciona uma matriz 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 contacto
GET /chat-sessions/{contactId}
Devolve todas as sessões de chat de um único contacto. Os mesmos parâmetros status, limit e includeMessages que 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 de sessão diferem entre os dois endpoints. A lista de sessões recentes chama-lhe
session_id(também contém os detalhes do contacto, uma vez que as sessões provêm de muitos contactos); a lista por contacto chama-lheid. Qualquer um dos valores é o que deve passar como{sessionId}ao obter o tópico completo abaixo.
Quando includeMessages=true, cada sessão ganha uma matriz messages cujas entradas contêm id, body, direction, timestamp, type, channel e status.
Obter um tópico de sessão de chat
GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Uma sessão de chat agrupa as mensagens de um contacto numa única janela de conversação. Este endpoint devolve o fio completo de uma única sessão, da mais antiga para a mais recente, juntamente com os metadados da sessão. Pode encontrar os IDs de sessão de um contacto 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 reporta status (ChatSessionOpened enquanto ativo, ChatSessionClosed após terminar), start_date_time, end_date_time, e um tag legível por humanos. A matriz messages utiliza os mesmos campos de mensagem que o endpoint de listagem.
Editar, eliminar e reagir a mensagens
Estes endpoints alteram uma mensagem após esta ter sido enviada. Dois deles contactam o canal do destinatário, bem como a sua própria cópia, por isso leia a introdução da secção antes de os configurar — o que é possível depende inteiramente do canal em que a conversa se encontra.
O que cada canal permite
| Ação | Canais que podem alterar a cópia do contacto | 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 |
| Eliminar para todos | Widget de chat, WhatsApp Web, Telegram, LinkedIn | 60 minutos no LinkedIn; os outros não têm 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 eliminação remove a mensagem da sua caixa de entrada, mas o contacto mantém a sua cópia, e não é possível editar ou reagir de todo.
Editar uma mensagem
POST /contacts/{contactId}/messages/{messageId}/edit
Reescreve uma mensagem que já enviou, no dispositivo do contacto e na sua cópia.
| Campo | Obrigatório | Descrição |
|---|---|---|
body |
Sim | O novo texto da mensagem. Não pode estar vazio e pode ter no máximo 4096 caracteres. |
Ao contrário da eliminação, isto falha de forma explícita quando o canal recusa: recebe um 409 e a sua cópia permanece exatamente como o contacto a tem, porque mostrar uma edição que nunca receberam deixaria os dois lados dessincronizados. O campo edit_reason indica-lhe o motivo — a janela de edição do canal expirou, o canal está desligado ou algo correu mal.
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, 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 eliminada, um canal que não permite edições de todo e uma mensagem demasiado antiga para o seu canal devolvem 400 — o pedido nunca chega ao canal.
Eliminar uma mensagem
DELETE /contacts/{contactId}/messages/{messageId}
Remove a mensagem da sua conversa e, quando o canal o permite, retira também a cópia do contacto. Sem corpo de pedido.
Isto responde sempre 200 quando a mensagem existia, mesmo que a cópia do contacto não pudesse ser retirada — a sua cópia foi eliminada, pelo que um erro seria enganador. Leia os três campos na resposta para informar o utilizador sobre o que aconteceu realmente:
| Campo | Descrição |
|---|---|
revoke_supported |
Se este canal consegue retirar mensagens. |
revoked |
Se a cópia no dispositivo do contacto 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 eliminadas não são removidas do histórico da conversa. Permanecem em
GET /contacts/{contactId}/messagescomis_deleted: truee umbodyemedia_urlvazios.
Eliminar várias mensagens de uma vez
POST /contacts/{contactId}/messages/bulk-delete
Limpa um lote de mensagens apenas do seu lado. O conteúdo e os anexos são esvaziados, mas nada é retirado no dispositivo do contacto — para também recuperar uma mensagem, elimine-a uma a 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 pedido. messageIds é aceite 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 a sua própria reação com emoji numa mensagem, ou retira-a enviando uma string vazia. As reações do próprio contacto nunca são alteradas.
| Campo | Obrigatório | Descrição |
|---|---|---|
emoji |
Sim | O emoji com o qual reagir, ou "" para remover a sua reação. Deve ser uma string única sem espaços, com no máximo 16 caracteres. |
Tal como a edição, isto falha em vez de mostrar uma reação que o contacto nunca recebeu, e a falha indica-lhe 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 por esse canal.409— o canal estava momentaneamente inacessível. Uma nova tentativa poderá 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 atualmente na mensagem, as suas e as do contacto. Num 409 ou 422, é devolvida inalterada, pelo que um cliente que faça a renderização diretamente a partir dela nunca mostrará uma reação que não tenha sido entregue.
Classificar ou marcar uma mensagem com estrela
PATCH /contacts/{contactId}/messages/{messageId}
Classifica uma mensagem com um polegar para cima ou para baixo e/ou marca-a como importante. Isto é apenas para registo do seu lado — nada é enviado ao contacto.
| Campo | Obrigatório | Descrição |
|---|---|---|
score |
Não | 1 polegar para cima, -1 polegar para baixo, 0 limpa a classificação. |
is_important |
Não | true adiciona uma estrela à mensagem, false remove a estrela. Tem de ser um booleano real, não a string "true". |
Envie pelo menos um dos dois, caso contrário receberá um 400. Apenas o que enviar é escrito, por isso adicionar uma estrela a uma mensagem nunca limpa a sua classificação e vice-versa — e a resposta reflete apenas os campos que 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
Pode limpar o estado de não lida tanto para mensagens específicas como para toda a conversação.
Marcar mensagens específicas como lidas
POST /contacts/{contactId}/messages/mark-read
Indique os IDs das mensagens a marcar como lidas.
| Campo | Obrigatório | Descrição |
|---|---|---|
message_ids |
Sim | Uma matriz não vazia de IDs de mensagem (até 500 por pedido). |
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 indicador de não lidas de toda a conversação do contacto na caixa de entrada. Não é necessário um corpo de pedido.
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 emblema de não lido de volta na conversa — útil quando alguém na sua equipa abriu uma conversa, mas está a devolvê-la. Não é necessário um corpo de pedido.
Este é um sinalizador exclusivo da caixa de entrada: não altera a data em que a conversa foi lida pela última vez, pelo que não é enviado qualquer recibo de leitura ao contacto em canais que os suportem.
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 completa como uma transcrição legível, em vez de percorrer as mensagens página a página. Cada endpoint de exportação aceita um filter de all (predefinição), text, media ou tool_use, correspondendo ao filtro na lista de mensagens.
Exportar a conversa de um contacto
GET /chat-exports/{contactId}
| Parâmetro de consulta | Obrigatório | Descrição |
|---|---|---|
format |
Não | txt (predefinição) devolve uma ligação de transferência para uma transcrição em texto simples. json devolve as mensagens como dados estruturados na resposta. |
filter |
Não | all (predefiniçã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 (a predefinição), data é, em vez disso, uma ligação de transferência para o ficheiro de transcrição gerado:
{
"success": true,
"data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}
A ligação de transferência tem uma duração curta. Obtenha o ficheiro assim que receber a ligação em vez de o armazenar — 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 contactos que estiveram ativos nas últimas X horas, numa única chamada.
| Parâmetro de consulta | Obrigatório | Descrição |
|---|---|---|
hours |
Sim | Quantas horas de atividade analisar. Deve ser um número inteiro positivo. |
format |
Não | json (predefinição) devolve uma entrada por contacto. txt devolve um único ficheiro de texto transferível com todas as conversas. |
limit |
Não | Número máximo de contactos a exportar. Predefinição 50, máximo 100. |
filter |
Não | all (predefiniçã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 ficheiro de texto, enviado como uma transferência em vez de JSON.
Esta chamada obtém o histórico completo de cada contacto correspondente, por isso mantenha
hourselimitmoderados em contas com muita atividade.
Enviar uma transcrição por e-mail ao contacto
POST /chat-exports/{contactId}/email
Envia ao contacto a sua própria transcrição da conversa por e-mail — o fluxo “enviar-me este chat por e-mail”, gerido a partir do seu próprio sistema.
| Campo | Obrigatório | Descrição |
|---|---|---|
recipient_email |
Não | Para onde enviar. Por predefinição, utiliza o endereço de e-mail guardado do contacto. |
via |
Não | auto (predefinição) escolhe a melhor rota, transactional envia como um e-mail do sistema, email_channel envia a partir do seu canal de e-mail ligado. |
note |
Não | Uma breve linha da sua parte apresentada 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 indica 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 de envio, não que já chegou à caixa de entrada.
Suspender ou retomar a IA para um contacto
PUT /contacts/{contactId}
Defina is_bot_active como false para impedir que a IA responda a um contacto e volte a true para devolver a conversação. Este é o interruptor de controlo que pretende quando um humano assume uma conversação: as mensagens de saída que envia com a API continuam a ser entregues enquanto o bot está suspenso.
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"
}
Suspender como parte da resposta
Se um humano estiver a assumir o controlo ao enviar uma resposta, pode suspender o bot no mesmo pedido em vez de efetuar uma segunda chamada. POST /contacts/{contactId}/send-message aceita dois sinalizadores opcionais:
| Campo | Descrição |
|---|---|
pauseBot |
true suspende a IA para este contacto à medida que a mensagem é enviada. |
clearIncompleteReply |
true descarta uma resposta do bot incompleta para que esta 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 suspensão foi aplicada.
Marcar um contacto como privado com
POST /contacts/bulk-flagtambém suspende o bot para o mesmo. Consulte Contactos para obter a lista completa de campos.
Criar a sua própria caixa de entrada
Tudo o que uma caixa de entrada precisa encontra-se nesta página e em Contactos:
| O que precisa | Endpoint |
|---|---|
| Listar conversas | GET /contacts |
| Ler uma conversa | GET /contacts/{contactId}/messages |
| Listar sessões de chat de um contacto | 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 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 |
| Classificar ou marcar uma mensagem | PATCH /contacts/{contactId}/messages/{messageId} |
| Marcar como lida | POST /contacts/{contactId}/mark-read |
| Devolver um chat à equipa | 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, subscreva os 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 mensagens devolvem o envelope de erro padrão:
{
"success": false,
"error": "Contact not found"
}
| Estado | Quando acontece num endpoint de mensagem |
|---|---|
400 |
Falta um campo obrigatório ou um parâmetro é inválido (limit, hours, filter, direction, status incorretos, uma matriz message_ids vazia ou com mais de 500 elementos, um cursor inválido, uma edição body vazia ou demasiado longa, um score fora de -1/0/1, ou um emoji com espaços ou mais de 16 caracteres). Também é devolvido quando uma mensagem não pode ser editada de todo — foi eliminada, o seu canal não permite edições ou já passou o período de edição desse canal. |
404 |
O contacto, 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 neste momento. Nada foi escrito: numa edição, edit_reason diz o motivo; numa reação, o canal estava momentaneamente inacessível e uma nova tentativa poderá funcionar. |
422 |
O contacto não pode receber mensagens de saída (não incomodar, privado ou um canal não suportado), ou uma reação nunca pode ser entregue nesta conversa (reaction_reason diz qual). |
Os códigos partilhados que qualquer endpoint pode devolver — 401, 403 (o seu plano não inclui acesso à API), 429 (limite de taxa) e 500 — estão listados com orientações de repetição em Erros e Paginação.
Próximos passos
- Webhooks — receba atualizações do estado de entrega em vez de consultar periodicamente.
- Contactos — crie e procure os contactos para os quais envia mensagens.
- Agendamentos — marque e gira agendamentos para os seus contactos.