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.
Ambos apenas encontram contactos que já existem. Nenhuma das chamadas cria um: um ID ou uma identidade que não corresponda a nada é devolvido como 404, não se tornando um novo contacto. Portanto, se estiver a enviar uma mensagem a alguém pela primeira vez, crie primeiro o contacto com POST /contacts ou, no WhatsApp Web, utilize Enviar diretamente para um número do WhatsApp Web abaixo, que cria o contacto na mesma chamada.
Enviar por ID de contacto
POST /contacts/{contactId}/send-message
| Campo | Obrigatório | Descrição |
|---|---|---|
body |
Sim | O texto da mensagem a enviar, até 65.536 caracteres. Um corpo de texto superior ao permitido pelo canal numa ú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, o widget de chat e canais personalizados) é entregue como várias mensagens por ordem, divididas por quebras de parágrafo ou de frase. A resposta contém então messageIds para cada parte e autoSplit: true. |
mediaUrl |
Não | URL de um ficheiro de multimédia (imagem, áudio, vídeo, documento) a anexar. |
mediaContentType |
Não | Tipo MIME do conteúdo multimédia anexado, por exemplo image/jpeg. Determinado a partir da extensão do ficheiro do URL quando omitido (.mp3 → audio/mpeg, .pdf → application/pdf); defina-o para um URL sem extensão. |
sendAsVoiceNote |
Não | Apenas WhatsApp Web, apenas áudio: entrega o áudio como uma nota de voz (a bolha de reprodução). Áudio que não seja OGG/Opus é convertido no momento do envio. O valor predefinido é false. |
pauseBot |
Não | true pausa a IA para este contacto à medida que a mensagem é enviada — para um humano assumir o controlo. Consulte Pausar ou retomar a IA. |
clearIncompleteReply |
Não | true descarta uma resposta do bot a meio para que esta não seja retomada após a sua mensagem. |
human_reply |
Não | true marca a mensagem como escrita por uma pessoa da sua equipa em vez de uma integração. A IA trata-a então como uma resposta de um colega de equipa na conversa, e uma resposta que a IA tinha em fila para a última mensagem do contacto é cancelada para que o contacto não receba duas respostas. Não pausa a IA; utilize pauseBot para isso. O valor predefinido é false. |
No LinkedIn, uma mensagem que envia desta forma, ou a partir da caixa de entrada, é entregue mesmo enquanto uma pessoa está a tratar do tópico do lado do LinkedIn. As respostas da própria IA e os seus seguimentos são retidos nesse tópico. Uma resposta retida é removida da conversa em vez de ser apresentada como falhada, porque nada foi enviado e não é utilizado qualquer crédito. A última resposta da IA antes de passar um tópico a 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 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, até 65.536 caracteres. Um corpo de mensagem mais longo do que o permitido pelo canal numa ú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 por ordem, divididas por quebras de parágrafo ou de frase. A resposta contém então messageIds para cada parte e autoSplit: true. |
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 conteúdo 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.
Envio no WhatsApp Web: variações e proteção contra rajadas
Dois aspetos aplicam-se ao body quando o contacto está no WhatsApp Web.
As chavetas 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 esse envio — as chavetas nunca chegam ao contacto. Utilize-as para dar a cada contacto uma mensagem de abertura diferente a partir do mesmo código de integração. O texto sem chavetas é enviado exatamente como escrito.
Rajadas de mensagens de abertura idênticas são recusadas. Se dez mensagens de abertura quase idênticas forem enviadas a partir de um número de WhatsApp Web no espaço de uma hora, para contactos que nunca lhe escreveram, as seguintes não serão entregues: o envio é aceite como habitualmente (continua a receber um messageId) e a mensagem fica com status: "failed" e error_code: "opener_burst", com um motivo legível pelo cliente. Tentar enviar o mesmo texto novamente não ajuda — varie o texto, aguarde uma hora e envie de novo. As respostas dentro de conversas existentes nunca são afetadas. A justificação encontra-se 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 procurar primeiro um contacto. Se o número ainda não for um contacto, o contacto é criado na mesma chamada, com a IA desativada para o mesmo, para que a mensagem pareça ter sido enviada manualmente e nenhum assistente assuma a conversa posteriormente. Um contacto existente é reutilizado tal 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 enviar. message ou mediaUrl têm de estar presentes. |
mediaUrl |
Não | URL público de um ficheiro a enviar. message ou mediaUrl têm de estar presentes. |
mediaContentType |
Não | Tipo MIME desse ficheiro, por exemplo image/jpeg. Determinado a partir do URL se não o indicar. |
sendAsVoiceNote |
Não | true envia um ficheiro de áudio como nota de voz em vez de como anexo. |
fromPhoneNumber |
Não | A partir de qual dos seus números do WhatsApp Web ligados enviar, em formato internacional. Assume por predefinição o número ao qual o contacto já pertence. |
campaignId |
Não | Utilize o horário de funcionamento deste Agente em vez do predefinido da conta. Tem de 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: enviar em nome de uma das 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 com 202:
{ "success": true, "queued": true, "contactId": "abc123" }
202 significa aceite, mas ainda não entregue. Fora do horário de funcionamento, o envio é retido e efetuado no próximo intervalo permitido, a menos que tenha passado ignoreActiveHours. Verifique o estado da própria mensagem com Listar as mensagens de um contacto utilizando o contactId que obteve aqui.
Quando não é processado:
| Estado | Código | O que aconteceu |
|---|---|---|
400 |
INVALID_PHONE_FORMAT |
O número não está em formato internacional, ou falta phoneNumber, ou faltam ambos message e mediaUrl. |
400 |
CONTACT_DND |
Esse contacto está em Não incomodar, pelo que não é enviado nada para o mesmo. |
400 |
CONTACT_PRIVATE |
Esse contacto está marcado como privado. |
404 |
CAMPAIGN_NOT_FOUND |
Nenhum Agente corresponde ao campaignId que passou. |
403 |
CAMPAIGN_FORBIDDEN |
Esse Agente pertence a outra conta. |
402 |
A conta não tem créditos restantes ou não existe nenhum número do WhatsApp Web ligado. |
Uma segunda chamada para o mesmo contacto enquanto um envio retido ainda está à espera responde com 409, pelo que nunca se acumula uma fila atrás de uma pessoa.
Registar uma nota numa conversa
POST /contacts/notes
Adiciona uma linha à conversa de um contacto sem a enviar. Utilize-a para contexto que a sua equipa e a IA devem ter, mas que o contacto nunca deve receber: um resumo de uma chamada telefónica que o seu agente de voz acabou de realizar, uma observação 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 a uma nota:
- Aparece no chat da caixa de entrada como um cartão amarelo de Nota, com o autor, caso tenha indicado um.
- A IA lê-a como parte do histórico da conversa, marcada como uma nota interna, para que a sua próxima resposta a tenha em conta.
- Nunca é enviada ao contacto, não consome créditos de mensagem e não aciona nada: sem resposta da IA, sem automatização, sem webhook, sem notificação, sem indicador de não lida. Não pausa a IA e não conta como uma resposta da sua equipa.
Encontre o contacto da mesma forma que em Enviar por identidade de contacto: através do seu ID ou de um channel mais o identificador correspondente. Uma nota apenas é enviada para um contacto que já exista; se não houver correspondência, o resultado é um 404.
| Campo | Obrigatório | Descrição |
|---|---|---|
contact_id |
Um dos dois | O ID do contacto. |
channel + identificador |
Um dos dois | channel mais phone_number (WhatsApp, WhatsApp Web, SMS), instagram_id, messenger_id ou telegram_user_id, conforme indicado em Enviar por identidade de contacto. |
body |
Sim | O texto da nota, até 4.000 caracteres. As quebras de linha são mantidas. |
author |
Não | Quem ou o que a escreveu, até 80 caracteres, por exemplo Voice agent ou Sarah (sales). Apresentado no cartão e ao IA. |
timestamp |
Não | Quando aconteceu, em milissegundos da época. O valor predefinido é agora. Utilize a hora de fim da chamada para que a nota fique no lugar correto na conversa. Não pode ser superior a 5 minutos no futuro; uma hora posterior será rejeitada com um 400. |
external_id |
Não | 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 contacto novamente não adiciona uma segunda nota; a resposta conterá então duplicate: true. Utilize-o para que um webhook reintentado não possa registar 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á tinha sido registada)
{
"success": true,
"messageId": "note_4c1f0e...",
"contactId": "contact123"
}
Uma nota aparece em Listar mensagens de um contacto com type: "note".
Gerar um rascunho de resposta com a IA
POST /contacts/{contactId}/draft-reply
Solicita ao agente de IA que gere a próxima resposta de uma conversação e devolve-lhe o texto. Nada é enviado. É o mesmo rascunho que o botão Gerar Resposta na caixa de entrada escreve: o agente utiliza a sua configuração, a sua base de conhecimentos e a conversação até ao momento, respondendo no idioma do contacto. Utilize-o para colocar um humano (ou a sua própria aplicação) entre a IA e o contacto: obtenha o rascunho, apresente-o para aprovação e, em seguida, envie-o com Enviar por ID de contacto, alterado ou tal como está.
- O rascunho é escrito pelo agente atribuído ao contacto. Um contacto que ainda não tenha um agente receberá o agente que responderia à sua próxima mensagem.
- Durante a elaboração do rascunho, o agente não executa quaisquer ferramentas ou funções, pelo que não ocorrem reservas, etiquetas, transferências ou outras ações.
- Nada é guardado na conversação e o contacto não vê nada.
- Um rascunho custa os mesmos créditos que uma resposta de IA desse agente nesta conversação, e nada quando a sua própria chave de IA está ligada.
- A conversação necessita de pelo menos uma mensagem.
Todos os campos do corpo são opcionais; um corpo vazio (ou a ausência de corpo) gera o rascunho da próxima resposta.
| Campo | Obrigatório | Descrição |
|---|---|---|
instruction |
Não | Uma instrução única para este rascunho, até 2.000 caracteres, o mesmo que manter premido Gerar Resposta na caixa de entrada. Por exemplo Offer Tuesday at 3pm ou Ask for their email address. |
campaign_id |
Não | Gerar rascunho ao abrigo desta campanha em vez do agente do contacto. |
purpose |
Não | chat_reply (predefinição) escreve uma mensagem para o contacto. faq_answer escreve uma resposta curta à pergunta do contacto que funciona por si só, para uma FAQ de base de conhecimentos. |
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ção ainda não tem mensagens, que os seus créditos terminaram ou que o contacto não tem um agente ou campanha a partir da qual gerar o rascunho (error indica qual). Um 404 significa que o contacto não existe ou que a chave de um membro da equipa está limitada a contactos que não consegue ver. A chave ou o membro da equipa necessita de permissão para editar mensagens.
Está a utilizar um cliente de IA através de MCP? A mesma ação está disponível como a ferramenta
generate_reply_draft.
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. Para uma mensagem com anexo, body começa com uma nota entre parênteses sobre o que foi recebido, seguida de 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 (recebida do contacto) ou outbound (enviada pela sua conta). |
channel |
Canal em que 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 assistência automatizada é marcada como tool_use. |
timestamp |
Hora de criação da mensagem em formato ISO 8601. |
media_url |
URL de um ficheiro multimédia anexo, se existir. Esta ligação deixa 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 restantes). Obtenha uma nova ligação com Transferir o anexo de uma mensagem. |
media_content_type |
Tipo MIME do suporte multimédia 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 ficam 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. |
faq_ids_used |
IDs das FAQs da Base de Conhecimento que a IA tinha à sua disposição quando escreveu esta resposta: as escolhidas para a última mensagem mais as mantidas de momentos anteriores da conversa. A mesma lista consta em todas as mensagens de uma resposta enviada em várias partes. Sempre uma matriz, vazia para mensagens recebidas, mensagens enviadas por pessoas, seguimentos automáticos e respostas da IA enviadas antes de 25 de setembro de 2026. |
faqs_used |
As mesmas FAQs com a respetiva pergunta: cada entrada tem id e question. question é null quando a FAQ foi eliminada entretanto. |
Transferir o anexo de uma mensagem
POST /chat-exports/media/download-url
Fornece-lhe uma nova ligação de transferência para o ficheiro anexado a uma mensagem: uma imagem, nota de voz, vídeo ou documento. A ligação funciona durante 1 hora. Utilize-a quando pretender guardar anexos noutro local (por exemplo, arquivar CV ou notas de voz enviadas por um contacto), ou quando o media_url numa mensagem ou um Webhook de Nova Mensagem já não abre.
Para encontrar mensagens com anexos, liste as mensagens de um contacto com filter=media. O id de cada mensagem e o ID do contacto constituem o messagePath.
| Campo do corpo | Obrigatório | Descrição |
|---|---|---|
messagePath |
Sim | Que mensagem, sob a forma 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 |
A ligação de transferência. Obtenha o ficheiro diretamente a partir dela, sem necessidade de chave de API. |
data.expiresInMs |
Durante quanto tempo a ligação funciona, em milissegundos (3600000 = 1 hora). Chame o endpoint novamente para obter uma nova ligação. |
| Estado | Quando |
|---|---|
400 |
O messagePath está em falta ou não se encontra no formato contacts/{contactId}/messages/{messageId}, ou a mensagem não tem nenhum anexo que possa ser transferido desta forma. Alguns anexos mais antigos estão armazenados no fornecedor do canal e não podem ser reemitidos, e um reel ou publicação partilhada do Instagram é uma ligação para o Instagram em vez de um ficheiro. |
403 |
O contacto não pertence à sua conta. |
404 |
Não existe nenhuma mensagem com esse ID nesse contacto. |
A utilizar um cliente de IA através de 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ção com um contacto. Abre-se na primeira mensagem recebida quando não existe nenhuma sessão aberta e fecha-se automaticamente 48 horas após a última mensagem recebida do contacto (cada nova mensagem recebida adia o fecho por mais 48 horas). O facto de a IA concluir um chat não fecha a sessão; apenas dispara o webhook de Chat Concluído. As sessões são a forma de organizar um longo histórico 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 (apenas mensagens de texto), 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 deve estar vazio e não deve ser mais longo do que o permitido pelo canal numa única mensagem (os mesmos limites por canal que em Enviar por ID de contacto; 4.096 quando a mensagem não tem canal). |
Ao contrário da eliminação, isto falha ruidosamente 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 colocaria os dois lados em desfasamento. O campo edit_reason indica-lhe o motivo — a janela de edição do canal fechou, o canal está desligado, a mensagem tem um anexo que o canal não consegue editar (media_not_editable: no WhatsApp Web apenas mensagens de texto podem ser editadas, não o texto sob uma fotografia, vídeo ou ficheiro), 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 enviando uma resposta, pode pausar o bot no mesmo pedido em vez de efetuar uma segunda chamada. POST /contacts/{contactId}/send-message aceita estes sinalizadores opcionais:
| Campo | Descrição |
|---|---|
pauseBot |
true pausa a IA para este contacto à medida que a mensagem é enviada. |
clearIncompleteReply |
true descarta uma resposta do bot a meio para que esta não seja retomada posteriormente. |
human_reply |
true marca a mensagem como uma resposta de um colega de equipa e cancela uma resposta que a IA tinha em 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 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.