Your AI Connector Docs

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/send e 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á um 404.

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 filter e direction são aplicados a cada página após a sua leitura, pelo que uma página filtrada pode conter menos itens do que limit. O next_cursor continua a avançar pela conversa completa, por isso continue a paginar até que next_cursor seja null.

cURL

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

JavaScript

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

Python

import requests

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

Resposta (200 OK):

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

Campos da mensagem

Campo Descrição
id ID ú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-lhe id. 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}/messages com is_deleted: true e um body e media_url vazios.

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 hours e limit moderados 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-flag també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.