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.
Ambos também apenas encontram contatos que já existem. Nenhuma das chamadas cria um: um ID ou uma identidade que não corresponde a nada retorna como 404, não se tornando um novo contato. Portanto, se você estiver enviando uma mensagem para alguém pela primeira vez, crie o contato primeiro com POST /contacts ou, no WhatsApp Web, use Enviar diretamente para um número do WhatsApp Web abaixo, que cria o contato na mesma chamada.
Enviar por ID de contato
POST /contacts/{contactId}/send-message
| Campo | Obrigatório | Descrição |
|---|---|---|
body |
Sim | O texto da mensagem a ser enviado, com até 65.536 caracteres. Um corpo maior do que o canal permite em uma única mensagem (1.500 na API do WhatsApp Business e SMS, 1.000 no Instagram, 2.000 no Messenger, 4.096 no Telegram e LinkedIn, 5.000 no LINE, 6.000 no TikTok, 7.000 no Viber, 65.536 no WhatsApp Web; sem limite para e-mail, widget de chat e canais personalizados) é entregue como várias mensagens em ordem, divididas em quebras de parágrafo ou frase. A resposta então carrega messageIds para cada parte e autoSplit: true. |
mediaUrl |
Não | URL de um arquivo de mídia (imagem, áudio, vídeo, documento) para anexar. |
mediaContentType |
Não | Tipo MIME da mídia anexada, por exemplo, image/jpeg. Determinado a partir da extensão do arquivo da URL quando omitido (.mp3 → audio/mpeg, .pdf → application/pdf); defina-o para uma URL sem extensão. |
sendAsVoiceNote |
Não | Apenas WhatsApp Web, apenas áudio: entrega o áudio como uma nota de voz (o balão de reprodução). Áudios que não estão no formato OGG/Opus são convertidos no momento do envio. O padrão é false. |
pauseBot |
Não | true pausa a IA para este contato conforme a mensagem é enviada — para um humano assumir. 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. |
human_reply |
Não | true marca a mensagem como escrita por uma pessoa da sua equipe em vez de uma integração. A IA então a trata como uma resposta de um colega de equipe na conversa, e uma resposta que a IA tinha na fila para a última mensagem do contato é cancelada para que o contato não receba duas respostas. Isso não pausa a IA; use pauseBot para isso. O padrão é false. |
No LinkedIn, uma mensagem enviada desta forma, ou a partir da caixa de entrada, é entregue mesmo enquanto uma pessoa está gerenciando o tópico no LinkedIn. As próprias respostas da IA e seus acompanhamentos são retidos em tal tópico. Uma resposta retida é removida do chat em vez de ser exibida como falha, porque nada foi enviado e nenhum crédito é utilizado. A última resposta da IA antes de ela passar um tópico para uma pessoa ainda é entregue.
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, com até 65.536 caracteres. Um corpo de texto maior do que o canal permite em uma única mensagem (1.500 na API do WhatsApp Business e SMS, 1.000 no Instagram, 2.000 no Messenger, 4.096 no Telegram e LinkedIn, 5.000 no LINE, 6.000 no TikTok, 7.000 no Viber, 65.536 no WhatsApp Web; sem limite para e-mail, widget de chat e canais personalizados) é entregue como várias mensagens em ordem, divididas em quebras de parágrafo ou frase. A resposta então carrega messageIds para cada parte e autoSplit: true. |
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 em 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.
Envio pelo WhatsApp Web: variações e proteção contra disparos em massa
Duas coisas se aplicam ao body quando o contato está no WhatsApp Web.
Chaves de Spintax são expandidas por envio. Um body de {Hi|Hello|Hey} there, quick question é enviado como uma das três saudações, escolhida para aquele envio — as chaves nunca chegam ao contato. Use isso para dar a cada contato uma mensagem de abertura diferente a partir do mesmo código de integração. Textos sem chaves são enviados exatamente como escritos.
Disparos de mensagens de abertura idênticas são recusados. Se dez mensagens de abertura quase idênticas forem enviadas de um número do WhatsApp Web dentro de uma hora para contatos que nunca escreveram para você, as próximas não serão entregues: o envio é aceito normalmente (você ainda recebe um messageId), e a mensagem fica com status: "failed" e error_code: "opener_burst", com um motivo legível para o cliente. Tentar enviar o mesmo texto novamente não ajuda — varie o texto, aguarde uma hora e envie novamente. Respostas dentro de conversas existentes nunca são afetadas. A justificativa está em Identical openers get numbers restricted.
Enviar diretamente para um número do WhatsApp Web
POST /whatsapp-web/send
Envie para um número de telefone no WhatsApp Web sem precisar procurar um contato primeiro. Se o número ainda não for um contato, o contato é criado na mesma chamada, com a IA desativada para ele, para que a mensagem pareça ter sido enviada manualmente e nenhum assistente assuma a conversa posteriormente. Um contato existente é reutilizado como está.
| Campo | Obrigatório | Descrição |
|---|---|---|
phoneNumber |
Sim | O número para o qual enviar a mensagem, em formato internacional (+31612345678). |
message |
Não | O texto a ser enviado. message ou mediaUrl devem estar presentes. |
mediaUrl |
Não | URL pública de um arquivo a ser enviado. message ou mediaUrl devem estar presentes. |
mediaContentType |
Não | Tipo MIME desse arquivo, por exemplo image/jpeg. Calculado a partir da URL quando você o omite. |
sendAsVoiceNote |
Não | true envia um arquivo de áudio como uma nota de voz em vez de um anexo. |
fromPhoneNumber |
Não | De qual dos seus números conectados do WhatsApp Web enviar, em formato internacional. O padrão é o número ao qual o contato já pertence. |
campaignId |
Não | Use o horário de funcionamento deste Agente em vez do padrão da conta. Deve ser um Agente na mesma conta. |
ignoreActiveHours |
Não | true envia imediatamente, independentemente do que o horário de funcionamento indique. |
sub_account_id |
Não | Para agências: envie em nome de uma de suas contas de cliente. |
curl -X POST "https://api.youraiconnector.com/v1/whatsapp-web/send?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+31612345678",
"message": "Hi Alex, your quote is ready."
}'
Uma chamada bem-sucedida responde 202:
{ "success": true, "queued": true, "contactId": "abc123" }
202 significa aceito, mas ainda não entregue. Fora do horário de funcionamento, o envio é retido e realizado no próximo intervalo permitido, a menos que você tenha passado ignoreActiveHours. Leia o status da própria mensagem com Listar mensagens de um contato usando o contactId que você obteve aqui.
Quando não é concluído:
| Status | Código | O que aconteceu |
|---|---|---|
400 |
INVALID_PHONE_FORMAT |
O número não está no formato internacional, ou phoneNumber está faltando, ou ambos message e mediaUrl estão. |
400 |
CONTACT_DND |
Esse contato está em Não perturbe, portanto, nada é enviado para ele. |
400 |
CONTACT_PRIVATE |
Esse contato está marcado como privado. |
404 |
CAMPAIGN_NOT_FOUND |
Nenhum Agente corresponde ao campaignId que você passou. |
403 |
CAMPAIGN_FORBIDDEN |
Esse Agente pertence a outra conta. |
402 |
A conta não tem créditos restantes ou nenhum número do WhatsApp Web está conectado. |
Uma segunda chamada para o mesmo contato enquanto um envio retido ainda está aguardando responde 409, portanto, uma fila nunca se acumula para a mesma pessoa.
Registrar uma nota em uma conversa
POST /contacts/notes
Adiciona uma linha à conversa de um contato sem enviá-la. Use para contextos que sua equipe e a IA devem ter, mas que o contato nunca deve receber: um resumo de uma chamada telefônica que seu agente de voz acabou de fazer, um comentário do seu CRM ou uma nota de um colega. Funciona em todos os canais (WhatsApp, SMS, Instagram, Messenger, Telegram, widget de chat, canais personalizados, etc.).
O que acontece com uma nota:
- Ela aparece no chat na caixa de entrada como um cartão amarelo de Nota, com o autor, caso você tenha enviado um.
- A IA a lê como parte do histórico da conversa, marcada como uma nota interna, para que sua próxima resposta a leve em consideração.
- Ela nunca é enviada ao contato, não custa créditos de mensagem e não aciona nada: sem resposta da IA, sem automação, sem webhook, sem notificação, sem selo de não lido. Ela não pausa a IA e não conta como uma resposta da sua equipe.
Encontre o contato da mesma forma que em Enviar por identidade do contato: seja pelo ID dele ou por um channel mais o identificador correspondente. Uma nota só é enviada para um contato que já existe; nada correspondente resulta em um 404.
| Campo | Obrigatório | Descrição |
|---|---|---|
contact_id |
Um dos dois | O ID do contato. |
channel + identifier |
Um dos dois | channel mais phone_number (WhatsApp, WhatsApp Web, SMS), instagram_id, messenger_id ou telegram_user_id, conforme em Enviar por identidade de contato. |
body |
Sim | O texto da nota, até 4.000 caracteres. Quebras de linha são mantidas. |
author |
Não | Quem ou o que escreveu, até 80 caracteres, por exemplo Voice agent ou Sarah (sales). Exibido no cartão e para a IA. |
timestamp |
Não | Quando aconteceu, em milissegundos da época (epoch). O padrão é agora. Use o horário de término da chamada para que a nota fique no lugar certo na conversa. Não pode ser mais de 5 minutos no futuro; um horário posterior é rejeitado com um 400. |
external_id |
Não | Seu próprio ID para esta nota, até 200 caracteres, por exemplo, o ID da chamada. Enviar o mesmo external_id para o mesmo contato novamente não adiciona uma segunda nota; a resposta então carrega duplicate: true. Use-o para que um webhook repetido não registre a mesma chamada duas vezes. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/notes" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "whatsapp",
"phone_number": "+31612345678",
"author": "Voice agent",
"body": "Voice call, 3:12. Asked about knee surgery waiting times, prefers a call back on Tuesday morning.",
"external_id": "call_8f2k1"
}'
Resposta (201, ou 200 com duplicate: true quando a external_id já foi registrada)
{
"success": true,
"messageId": "note_4c1f0e...",
"contactId": "contact123"
}
Uma nota aparece em Listar mensagens de um contato com type: "note".
Gere um rascunho de resposta com a IA
POST /contacts/{contactId}/draft-reply
Solicita ao agente de IA que gerencia uma conversa que escreva a próxima resposta e retorna o texto para você. Nada é enviado. É o mesmo rascunho que o botão Gerar Resposta na caixa de entrada escreve: o agente usa sua configuração, sua base de conhecimento e a conversa até o momento, e responde no idioma do contato. Use isso para colocar um humano (ou seu próprio aplicativo) entre a IA e o contato: busque o rascunho, exiba-o para aprovação e, em seguida, envie-o com Enviar por ID de contato, alterado ou como está.
- O rascunho é escrito pelo agente atribuído ao contato. Um contato que ainda não possui um agente recebe o agente que responderia à sua próxima mensagem.
- Ao redigir, o agente não executa nenhuma ferramenta ou função, portanto, nenhum agendamento, marcação, transferência ou outra ação ocorre.
- Nada é armazenado na conversa e o contato não vê nada.
- Um rascunho custa os mesmos créditos que uma resposta de IA desse agente nesta conversa, e nada quando sua própria chave de IA está conectada.
- A conversa precisa de pelo menos uma mensagem.
Todos os campos do corpo são opcionais; um corpo vazio (ou nenhum corpo) redige a próxima resposta.
| Campo | Obrigatório | Descrição |
|---|---|---|
instruction |
Não | Uma instrução única para este rascunho, de até 2.000 caracteres, o mesmo que manter pressionado Gerar Resposta na caixa de entrada. Por exemplo Offer Tuesday at 3pm ou Ask for their email address. |
campaign_id |
Não | Redija sob esta campanha em vez do agente do contato. |
purpose |
Não | chat_reply (padrão) escreve uma mensagem para o contato. faq_answer escreve uma resposta curta para a pergunta do contato que funciona por conta própria, para uma FAQ de base de conhecimento. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/draft-reply" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "instruction": "Offer Tuesday at 3pm for the consultation" }'
Resposta (200)
{
"success": true,
"contact_id": "contact123",
"draft": "Hi Sara, Tuesday at 3pm works for the consultation. Shall I put you down for it?"
}
Um 400 significa que a conversa ainda não tem mensagens, seus créditos acabaram ou o contato não tem agente ou campanha para redigir (o error diz qual). Um 404 significa que o contato não existe ou que a chave de um membro da equipe está limitada a contatos que ele não pode ver. A chave ou o membro da equipe precisa de permissão para editar mensagens.
Usando um cliente de IA via MCP? A mesma ação está disponível como a ferramenta
generate_reply_draft.
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 único da mensagem. |
body |
Conteúdo de texto da mensagem. Para uma mensagem com anexo, body começa com uma nota entre colchetes do que chegou, seguida por qualquer legenda, por exemplo [THE CONTACT UPLOADED AN IMAGE] Here is my CV ou [THE CONTACT UPLOADED A VOICE NOTE] - [TRANSCRIPTION: ...]. Notas de voz e vídeos incluem a transcrição. |
direction |
inbound (recebido do contato) ou outbound (enviado 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 |
Horário ISO 8601 em que a mensagem foi criada. |
media_url |
URL de um arquivo de mídia anexado, se houver. Este link para de funcionar 7 dias após a chegada da mensagem, em todos os canais (WhatsApp Business API, WhatsApp Web, Instagram, Messenger, Telegram, widget de chat e os demais). Obtenha um novo com Baixar anexo de uma mensagem. |
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 classificação da mensagem: 1 polegar para cima, -1 polegar para baixo, 0 quando não foi classificada. Veja Classificar 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. |
faq_ids_used |
IDs das FAQs da Base de Conhecimento que a IA tinha à disposição quando escreveu esta resposta: as escolhidas para a mensagem mais recente, além das mantidas anteriormente na conversa. A mesma lista está em cada mensagem de uma resposta enviada em várias partes. Sempre um array, vazio para mensagens recebidas, mensagens enviadas por pessoas, acompanhamentos automáticos e respostas da IA enviadas antes de 25 de setembro de 2026. |
faqs_used |
As mesmas FAQs com suas perguntas: cada entrada tem id e question. question é null quando a FAQ foi excluída desde então. |
Baixar o anexo de uma mensagem
POST /chat-exports/media/download-url
Fornece um novo link de download para o arquivo anexado a uma mensagem: uma imagem, nota de voz, vídeo ou documento. O link funciona por 1 hora. Use-o quando quiser salvar anexos em outro lugar (por exemplo, arquivar currículos ou notas de voz enviadas por um contato), ou quando o media_url em uma mensagem ou um Webhook de Nova Mensagem não abrir mais.
Para encontrar mensagens com anexos, liste as mensagens de um contato com filter=media. O id de cada mensagem e o ID do contato compõem o messagePath.
| Campo do corpo | Obrigatório | Descrição |
|---|---|---|
messagePath |
Sim | Qual mensagem, no formato contacts/{contactId}/messages/{messageId}. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/chat-exports/media/download-url" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/chat-exports/media/download-url", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ messagePath: "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO" }),
});
const { data } = await res.json();
console.log(data.url); // download the file within the hour
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/chat-exports/media/download-url",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"messagePath": "contacts/contact123/messages/aB3dE5fG7hI9jK1lM2nO"},
)
file_url = res.json()["data"]["url"]
Resposta (200 OK):
{
"success": true,
"data": {
"url": "https://storage.googleapis.com/...",
"expiresInMs": 3600000
}
}
| Campo | Descrição |
|---|---|
data.url |
O link de download. Obtenha o arquivo diretamente por ele, sem necessidade de chave de API. |
data.expiresInMs |
Por quanto tempo o link funciona, em milissegundos (3600000 = 1 hora). Chame o endpoint novamente para obter um novo link. |
| Status | Quando |
|---|---|
400 |
messagePath está faltando ou não está no formato contacts/{contactId}/messages/{messageId}, ou a mensagem não possui anexo que possa ser baixado desta forma. Alguns anexos mais antigos são armazenados no provedor do canal e não podem ser reemitidos, e um reel ou post compartilhado do Instagram é um link para o Instagram, e não um arquivo. |
403 |
O contato não pertence à sua conta. |
404 |
Nenhuma mensagem com esse ID existe nesse contato. |
Usando um cliente de IA via MCP? A mesma ação está disponível como a ferramenta
get_chat_media_download_url.
Listar sessões de chat
Uma sessão de chat é uma janela de conversa com um contato. Ela é aberta na primeira mensagem recebida quando nenhuma sessão está aberta, e é fechada automaticamente 48 horas após a última mensagem recebida do contato (cada nova mensagem recebida estende o fechamento por mais 48 horas). A IA concluir um chat não encerra a sessão; ela apenas dispara o webhook de Chat Concluído. 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 | Chat widget, WhatsApp Web (apenas mensagens de texto), Telegram, LinkedIn | Nenhum no chat widget, 15 minutos no WhatsApp Web, 48 horas no Telegram, 60 minutos no LinkedIn |
| Excluir para todos | Chat widget, 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 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 não pode ser maior do que o canal permite em uma única mensagem (os mesmos limites por canal que Enviar por ID de contato; 4.096 quando a mensagem não tem canal). |
Diferente da exclusão, isso falha de forma explícita quando o canal recusa: você recebe um 409 e sua cópia é deixada exatamente como o contato a possui, porque mostrar uma edição que eles nunca receberam deixaria os dois lados dessincronizados. O campo edit_reason informa o motivo — a janela de edição do canal foi encerrada, o canal está desconectado, a mensagem possui um anexo que o canal não pode editar (media_not_editable: no WhatsApp Web, apenas mensagens de texto podem ser editadas, não o texto sob uma foto, vídeo ou arquivo), ou algo mais 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 estas 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. |
human_reply |
true marca a mensagem como uma resposta de um colega de equipe e cancela uma resposta que a IA tinha na fila. Pausar ainda requer pauseBot. |
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,
"human_reply": 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.