Berichten & Gesprekken
Met de Messages API kun je een bericht naar elke contactpersoon sturen, een conversatie teruglezen, een reeds verzonden bericht corrigeren of verwijderen, op een bericht reageren, een volledige chat-sessie ophalen, een transcript exporteren en chats als gelezen of ongelezen markeren — en dat alles zonder de inbox te openen.
Alle paden op deze pagina zijn relatief ten opzichte van de basis-URL https://api.youraiconnector.com/v1. Voor elk verzoek is je API-sleutel vereist — zie Authenticatie voor de volledige lijst met manieren om deze te verzenden. De onderstaande voorbeelden gebruiken de X-API-Key-header, waarbij één cURL-voorbeeld ook de ?apiKey=-queryvorm laat zien.
Hoe aflevering werkt: Het verzenden van een bericht wacht niet tot het is aangekomen. De API accepteert je bericht, reageert onmiddellijk met een bericht-ID en levert het vervolgens op de achtergrond af via het kanaal van de contactpersoon (WhatsApp, SMS, Instagram, enzovoort). Om bij te houden of een bericht daadwerkelijk is afgeleverd of gelezen, kun je luisteren naar statusupdates met Webhooks — ga niet pollen. De verzendreactie bevestigt alleen dat het bericht is geaccepteerd.
Een bericht verzenden
Er zijn twee manieren om te verzenden. Kies degene die past bij hoe je de contactpersoon al identificeert:
- Verzenden op contact-ID — je kent het ID van de contactpersoon al (je hebt de contactpersoon bijvoorbeeld via de API aangemaakt of via een webhook verkregen). Gebruik
POST /contacts/{contactId}/send-message. - Verzenden op contact-identiteit — je kent het telefoonnummer, Instagram-ID, enz. van de contactpersoon, maar niet hun interne ID. Gebruik
POST /contacts/senden laat het platform de juiste contactpersoon vinden.
Beide methoden plaatsen het bericht op dezelfde manier in de wachtrij en leveren het af via het kanaal waarop de contactpersoon zich bevindt. Je kiest zelf geen transportmethode — het platform routeert WhatsApp-contacten via WhatsApp, SMS-contacten via SMS, enzovoort.
Beide vinden ook alleen contacten die al bestaan. Geen van beide aanroepen maakt er een aan: een ID of een identiteit die nergens mee overeenkomt, wordt teruggegeven als 404; het wordt geen nieuw contact. Dus als je iemand voor het eerst een bericht stuurt, maak dan eerst het contact aan met POST /contacts, of gebruik op WhatsApp Web hieronder Direct naar een WhatsApp Web-nummer verzenden, wat het contact in dezelfde aanroep aanmaakt.
Verzenden op contact-ID
POST /contacts/{contactId}/send-message
| Veld | Vereist | Beschrijving |
|---|---|---|
body |
Ja | De berichttekst die moet worden verzonden, tot 65.536 tekens. Een berichttekst die langer is dan het kanaal toestaat in één bericht (1.500 op de WhatsApp Business API en SMS, 1.000 op Instagram, 2.000 op Messenger, 4.096 op Telegram en LinkedIn, 5.000 op LINE, 6.000 op TikTok, 7.000 op Viber, 65.536 op WhatsApp Web; geen limiet voor e-mail, de chatwidget en aangepaste kanalen) wordt als meerdere berichten op volgorde afgeleverd, gesplitst bij alinea- of zinsafbrekingen. Het antwoord bevat dan messageIds voor elk deel en autoSplit: true. |
mediaUrl |
Nee | URL van een mediabestand (afbeelding, audio, video, document) om bij te voegen. |
mediaContentType |
Nee | MIME-type van de bijgevoegde media, bijv. image/jpeg. Wordt bepaald aan de hand van de bestandsextensie van de URL indien weggelaten (.mp3 → audio/mpeg, .pdf → application/pdf); stel dit in voor een URL zonder extensie. |
sendAsVoiceNote |
Nee | Alleen WhatsApp Web, alleen audio: lever de audio af als een spraakbericht (de afspeelbubbel). Audio die geen OGG/Opus is, wordt geconverteerd op het moment van verzenden. Standaard ingesteld op false. |
pauseBot |
Nee | true pauzeert de AI voor dit contact wanneer het bericht wordt verzonden — voor het geval een mens het overneemt. Zie De AI pauzeren of hervatten. |
clearIncompleteReply |
Nee | true verwijdert een halfvoltooid bot-antwoord zodat het niet wordt hervat na uw bericht. |
human_reply |
Nee | true markeert het bericht als geschreven door een persoon in uw team in plaats van door een integratie. De AI behandelt het vervolgens als een antwoord van een teamgenoot in het gesprek, en een antwoord dat de AI in de wachtrij had staan voor het laatste bericht van het contact wordt geannuleerd, zodat het contact niet twee antwoorden krijgt. Het pauzeert de AI niet; gebruik pauseBot daarvoor. Standaard ingesteld op false. |
Op LinkedIn wordt een bericht dat je op deze manier of vanuit de inbox verstuurt, afgeleverd, zelfs terwijl een persoon de thread aan de LinkedIn-kant beheert. De eigen antwoorden en follow-ups van de AI worden in een dergelijke thread tegengehouden. Een tegengehouden antwoord wordt uit de chat verwijderd in plaats van als mislukt weergegeven, omdat er niets is verzonden en er geen tegoed wordt verbruikt. Het laatste antwoord van de AI voordat deze een thread overdraagt aan een persoon, wordt nog steeds afgeleverd.
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"])
Antwoord (200 OK):
{
"success": true,
"messageId": "aB3dE5fG7hI9jK1lM2nO",
"contactId": "contact123",
"channel": "whatsapp",
"message": "Message created successfully. Delivery is being processed."
}
Verzenden op contact-identiteit
POST /contacts/send
Gebruik dit wanneer je niet over het interne ID van de contactpersoon beschikt. Geef de berichttekst body op, plus ofwel een contact_id, ofwel een channel samen met het identiteitsveld dat overeenkomt met dat kanaal.
| Veld | Verplicht | Beschrijving |
|---|---|---|
body |
Ja | De te verzenden berichttekst, tot 65.536 tekens. Een berichttekst die langer is dan het kanaal toestaat in één bericht (1.500 op de WhatsApp Business API en SMS, 1.000 op Instagram, 2.000 op Messenger, 4.096 op Telegram en LinkedIn, 5.000 op LINE, 6.000 op TikTok, 7.000 op Viber, 65.536 op WhatsApp Web; geen limiet voor e-mail, de chatwidget en aangepaste kanalen) wordt als meerdere berichten op volgorde afgeleverd, gesplitst bij alinea- of zinsafbrekingen. Het antwoord bevat dan messageIds voor elk deel en autoSplit: true. |
contact_id |
Nee | ID van een bestaand contact. Indien ingesteld, zijn de onderstaande identiteitsvelden niet nodig. |
channel |
Nee | Kanaal om via te verzenden. Verplicht wanneer contact_id niet is opgegeven. Een van de 14 kanalen die geschikt zijn voor uitgaande berichten: whatsapp, whatsapp_web, sms, instagram, instagram_private, messenger, telegram, chat-widget, custom, email, line, imessage, linkedin, viber. |
phone_number |
Nee | Telefoonnummer van het contact in internationaal formaat. Gebruikt met whatsapp, whatsapp_web en sms. |
instagram_id |
Nee | Instagram-gebruikers-ID van het contact. Gebruikt met instagram. |
messenger_id |
Nee | Messenger-gebruikers-ID van het contact. Gebruikt met messenger. |
telegram_user_id |
Nee | Telegram-gebruikers-ID van het contact. Gebruikt met telegram. |
media_url |
Nee | URL van een mediabestand om bij te voegen. |
media_content_type |
Nee | MIME-type van de bijgevoegde media, bijv. image/jpeg. |
Welke kanalen kunnen worden opgelost op basis van identiteit. Slechts zes van de 14 accepteren een identiteitsveld in plaats van een contact_id: whatsapp, whatsapp_web en sms worden opgezocht via phone_number, instagram via instagram_id, messenger via messenger_id, en telegram via telegram_user_id. De andere acht — instagram_private, chat-widget, custom, email, line, imessage, linkedin en viber — hebben geen openbare identiteit om op te zoeken, dus verzenden via die kanalen vereist contact_id; het alleen doorgeven van channel resulteert in een 400 die aangeeft dat contact_id vereist is.
cURL (met gebruik van de ?apiKey=-queryvorm)
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"])
Antwoord (201 Created):
{
"success": true,
"message_id": "aB3dE5fG7hI9jK1lM2nO",
"contact_id": "contact123",
"channel": "whatsapp"
}
Waarom een bericht kan worden geweigerd: Een contactpersoon met de modus ‘niet storen’ of privémodus ingeschakeld kan geen uitgaande berichten ontvangen — het verzoek mislukt met een
422. Als er geen contactpersoon overeenkomt met het ID of de identiteit die je hebt opgegeven, krijg je een404.
Verzenden via WhatsApp Web: variaties en burst-beveiliging
Twee zaken zijn van toepassing op body wanneer de contactpersoon WhatsApp Web gebruikt.
Spintax-accolades worden per verzending uitgevouwen. Een body van {Hi|Hello|Hey} there, quick question wordt verzonden als een van de drie begroetingen, gekozen voor die specifieke verzending — de accolades bereiken de contactpersoon nooit. Gebruik dit om elke contactpersoon een ander openingsbericht te sturen vanuit dezelfde integratiecode. Tekst zonder accolades wordt exact zo verzonden als geschreven.
Bursts van identieke openingsberichten worden geweigerd. Als er binnen een uur tien vrijwel identieke openingsberichten worden verzonden vanaf één WhatsApp Web-nummer naar contactpersonen die nog nooit naar u hebben geschreven, worden verdere berichten niet afgeleverd: de verzending wordt zoals gebruikelijk geaccepteerd (u krijgt nog steeds een messageId), en het bericht blijft vervolgens staan met status: "failed" en error_code: "opener_burst", voorzien van een voor de klant leesbare reden. Het opnieuw proberen van dezelfde tekst helpt niet — varieer de tekst, wacht een uur en verzend opnieuw. Antwoorden binnen bestaande gesprekken worden nooit beïnvloed. De reden hiervoor staat in Identieke openers leiden tot beperkingen op nummers.
Direct naar een WhatsApp Web-nummer verzenden
POST /whatsapp-web/send
Verzend naar een telefoonnummer op WhatsApp Web zonder eerst een contact op te zoeken. Als het nummer nog geen contact is, wordt het contact in dezelfde aanroep aangemaakt, met de AI uitgeschakeld, zodat het bericht overkomt als een handmatig verzonden bericht en er daarna geen assistent het gesprek overneemt. Een bestaand contact wordt gebruikt zoals het is.
| Veld | Verplicht | Beschrijving |
|---|---|---|
phoneNumber |
Ja | Het nummer waarnaar het bericht moet worden verzonden, in internationaal formaat (+31612345678). |
message |
Nee | De tekst die moet worden verzonden. Of message of mediaUrl moet aanwezig zijn. |
mediaUrl |
Nee | Openbare URL van een bestand om te verzenden. Of message of mediaUrl moet aanwezig zijn. |
mediaContentType |
Nee | MIME-type van dat bestand, bijvoorbeeld image/jpeg. Wordt bepaald op basis van de URL als je dit weglaat. |
sendAsVoiceNote |
Nee | true verzendt een audiobestand als een spraakbericht in plaats van als bijlage. |
fromPhoneNumber |
Nee | Vanaf welk van je verbonden WhatsApp Web-nummers moet worden verzonden, in internationaal formaat. Standaard is dit het nummer waartoe het contact al behoort. |
campaignId |
Nee | Gebruik de actieve uren van deze Agent in plaats van de standaardinstelling van het account. Moet een Agent op hetzelfde account zijn. |
ignoreActiveHours |
Nee | true verzendt direct, ongeacht wat de actieve uren aangeven. |
sub_account_id |
Nee | Voor bureaus: verzenden namens een van je klantaccounts. |
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."
}'
Een succesvolle aanroep beantwoordt met 202:
{ "success": true, "queued": true, "contactId": "abc123" }
202 betekent geaccepteerd, nog niet afgeleverd. Buiten de actieve uren wordt de verzending vastgehouden en verstuurd in het volgende toegestane tijdslot, tenzij je ignoreActiveHours hebt doorgegeven. Lees de status van het bericht zelf uit met Berichten van een contact weergeven met de contactId die je hier hebt gekregen.
Wanneer het niet lukt:
| Status | Code | Wat er is gebeurd |
|---|---|---|
400 |
INVALID_PHONE_FORMAT |
Het nummer is niet in internationaal formaat, of phoneNumber ontbreekt, of zowel message als mediaUrl ontbreken. |
400 |
CONTACT_DND |
Dat contact staat op ‘Niet storen’, dus er wordt niets uitgaand naar hen verzonden. |
400 |
CONTACT_PRIVATE |
Dat contact is gemarkeerd als privé. |
404 |
CAMPAIGN_NOT_FOUND |
Geen enkele Agent komt overeen met de campaignId die je hebt doorgegeven. |
403 |
CAMPAIGN_FORBIDDEN |
Die Agent behoort tot een ander account. |
402 |
Het account heeft geen credits meer, of er is geen WhatsApp Web-nummer verbonden. |
Een tweede aanroep voor hetzelfde contact terwijl er nog een verzending in de wachtrij staat, beantwoordt met 409, zodat er nooit een wachtrij achter één persoon opbouwt.
Een notitie toevoegen aan een gesprek
POST /contacts/notes
Voegt een regel toe aan het gesprek van een contactpersoon zonder deze te verzenden. Gebruik dit voor context die jouw team en de AI moeten hebben, maar die de contactpersoon nooit mag ontvangen: een samenvatting van een telefoongesprek dat je voice-agent zojuist heeft gevoerd, een opmerking uit je CRM of een notitie van een collega. Het werkt op elk kanaal (WhatsApp, sms, Instagram, Messenger, Telegram, de chatwidget, aangepaste kanalen enzovoort).
Wat er met een notitie gebeurt:
- Het verschijnt in de chat in de inbox als een gele Notitie-kaart, met de auteur als je die hebt opgegeven.
- De AI leest het als onderdeel van de gespreksgeschiedenis, gemarkeerd als een interne notitie, zodat de volgende reactie hiermee rekening houdt.
- Het wordt nooit naar de contactpersoon verzonden, kost geen berichtcredits en activeert niets: geen AI-reactie, geen automatisering, geen webhook, geen melding, geen ongelezen-badge. Het pauzeert de AI niet en telt niet als een reactie van je team.
Zoek de contactpersoon op dezelfde manier als bij Verzenden op basis van contactidentiteit: ofwel via het ID, of via een channel plus de bijbehorende identificatie. Een notitie gaat alleen naar een contactpersoon die al bestaat; als er geen overeenkomst is, is dat een 404.
| Veld | Vereist | Beschrijving |
|---|---|---|
contact_id |
Een van de twee | De ID van de contactpersoon. |
channel + identifier |
Een van de twee | channel plus phone_number (WhatsApp, WhatsApp Web, SMS), instagram_id, messenger_id of telegram_user_id, zoals in Verzenden via contactidentiteit. |
body |
Ja | De tekst van de notitie, maximaal 4.000 tekens. Regeleinden blijven behouden. |
author |
Nee | Wie of wat het heeft geschreven, maximaal 80 tekens, bijvoorbeeld Voice agent of Sarah (sales). Wordt getoond op de kaart en aan de AI. |
timestamp |
Nee | Wanneer het gebeurde, in epoch-milliseconden. Standaard is dit nu. Gebruik de eindtijd van het gesprek zodat de notitie op de juiste plek in de thread staat. Het mag niet meer dan 5 minuten in de toekomst liggen; een latere tijd wordt afgewezen met een 400. |
external_id |
Nee | Uw eigen ID voor deze notitie, maximaal 200 tekens, bijvoorbeeld de gespreks-ID. Het opnieuw verzenden van dezelfde external_id voor dezelfde contactpersoon voegt geen tweede notitie toe; het antwoord bevat dan duplicate: true. Gebruik dit zodat een opnieuw geprobeerde webhook niet hetzelfde gesprek twee keer kan loggen. |
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"
}'
Antwoord (201, of 200 met duplicate: true wanneer de external_id al was gelogd)
{
"success": true,
"messageId": "note_4c1f0e...",
"contactId": "contact123"
}
Een notitie verschijnt in De berichten van een contactpersoon weergeven met type: "note".
Een antwoordconcept genereren met de AI
POST /contacts/{contactId}/draft-reply
Vraagt de AI-agent die een gesprek afhandelt om het volgende antwoord te schrijven en geeft je de tekst terug. Er wordt niets verzonden. Het is hetzelfde concept dat de knop Antwoord genereren in de inbox schrijft: de agent gebruikt zijn instellingen, zijn kennisbank en het gesprek tot nu toe, en antwoordt in de taal van de contactpersoon. Gebruik dit om een mens (of je eigen app) tussen de AI en de contactpersoon te plaatsen: haal het concept op, toon het ter goedkeuring en verzend het vervolgens met Verzenden op contact-ID, gewijzigd of zoals het is.
- Het concept wordt geschreven door de agent die aan de contactpersoon is toegewezen. Een contactpersoon die nog geen agent heeft, krijgt de agent die op het volgende bericht zou antwoorden.
- Tijdens het opstellen voert de agent geen tools of functies uit, dus er vinden geen boekingen, labels, overdrachten of andere acties plaats.
- Er wordt niets opgeslagen in het gesprek en de contactpersoon ziet niets.
- Een concept kost evenveel credits als één AI-antwoord van die agent in dit gesprek, en niets wanneer je eigen AI-sleutel is gekoppeld.
- Het gesprek moet ten minste één bericht bevatten.
Alle hoofdtekstvelden zijn optioneel; een lege hoofdtekst (of geen hoofdtekst) stelt het volgende antwoord op.
| Veld | Vereist | Beschrijving |
|---|---|---|
instruction |
Nee | Een eenmalige instructie voor dit concept, tot 2.000 tekens, hetzelfde als lang drukken op Antwoord genereren in de inbox. Bijvoorbeeld Offer Tuesday at 3pm of Ask for their email address. |
campaign_id |
Nee | Concept onder deze campagne in plaats van de agent van de contactpersoon. |
purpose |
Nee | chat_reply (standaard) schrijft een bericht aan de contactpersoon. faq_answer schrijft een kort antwoord op de vraag van de contactpersoon dat op zichzelf werkt, voor een kennisbank-FAQ. |
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" }'
Antwoord (200)
{
"success": true,
"contact_id": "contact123",
"draft": "Hi Sara, Tuesday at 3pm works for the consultation. Shall I put you down for it?"
}
Een 400 betekent dat het gesprek nog geen berichten bevat, je credits op zijn, of de contactpersoon geen agent of campagne heeft om vanuit te schrijven (error geeft aan welke). Een 404 betekent dat de contactpersoon niet bestaat, of dat de sleutel van een teamlid beperkt is tot contactpersonen die het niet kan zien. De sleutel of het teamlid heeft toestemming nodig om berichten te bewerken.
Gebruik je een AI-client via MCP? Dezelfde actie is beschikbaar als de
generate_reply_drafttool.
Berichten van een contactpersoon weergeven
GET /contacts/{contactId}/messages
Geeft de berichten van een contactpersoon terug, de nieuwste eerst, met cursor-gebaseerde paginering.
| Query-parameter | Verplicht | Beschrijving |
|---|---|---|
limit |
Nee | Paginagrootte. Standaard 50, maximum 100. |
cursor |
Nee | De next_cursor-waarde van een vorig antwoord. Geeft berichten terug die ouder zijn dan de cursor. |
filter |
Nee | Filteren op inhoudstype: all (standaard), text, media of tool_use. |
direction |
Nee | Filteren op richting: all (standaard), inbound (ontvangen van de contactpersoon) of outbound (verzonden door jou). |
Opmerking over filteren en paginering: De
filter- endirection-filters worden toegepast op elke pagina nadat deze is gelezen, dus een gefilterde pagina kan minder items bevatten danlimit. Denext_cursorgaat nog steeds door het volledige gesprek, dus blijf pagineren totdatnext_cursorgelijk is aannull.
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"])
Antwoord (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"
}
Berichtvelden
| Veld | Beschrijving |
|---|---|
id |
Uniek ID van het bericht. |
body |
Tekstinhoud van het bericht. Voor een bericht met een bijlage begint body met een notitie tussen haakjes over wat er is binnengekomen, gevolgd door eventuele bijschriften, bijvoorbeeld [THE CONTACT UPLOADED AN IMAGE] Here is my CV of [THE CONTACT UPLOADED A VOICE NOTE] - [TRANSCRIPTION: ...]. Spraaknotities en video’s bevatten de transcriptie. |
direction |
inbound (ontvangen van de contactpersoon) of outbound (verzonden door jouw account). |
channel |
Kanaal waarop het bericht is verzonden of ontvangen (bijv. whatsapp, sms, instagram). |
status |
Huidige afleverstatus, bijv. Created, sent, delivered, read, failed. |
type |
Berichttype. Berichten met platte tekst hebben een null-type; activiteit van geautomatiseerde assistent-tools is gemarkeerd als tool_use. |
timestamp |
ISO 8601-tijdstip waarop het bericht is aangemaakt. |
media_url |
URL van een bijgevoegd mediabestand, indien aanwezig. Deze link werkt 7 dagen na ontvangst van het bericht niet meer, op elk kanaal (WhatsApp Business API, WhatsApp Web, Instagram, Messenger, Telegram, chatwidget en de rest). Haal een nieuwe op met Een bijlage van een bericht downloaden. |
media_content_type |
MIME-type van de bijgevoegde media, indien aanwezig. |
bot_reply |
true wanneer het bericht is gegenereerd door de AI-assistent. |
score |
Jouw beoordeling van het bericht: 1 duim omhoog, -1 duim omlaag, 0 wanneer het niet is beoordeeld. Zie Een bericht beoordelen of een ster geven. |
is_important |
true wanneer het bericht een ster heeft gekregen. |
is_deleted |
true wanneer het bericht is verwijderd. Verwijderde berichten blijven in de lijst staan, maar hun body en media_url zijn leeg. |
reactions |
Emoji-reacties op het bericht, van beide kanten. Altijd een array — leeg als er geen zijn. Elk item heeft emoji, from_phone_number, from_me (true wanneer de reactie van jou is) en reacted_at. |
faq_ids_used |
ID’s van de Knowledge Base-FAQ’s die de AI voor zich had toen dit antwoord werd geschreven: de FAQ’s die zijn gekozen voor het laatste bericht plus de FAQ’s die uit eerdere gesprekken zijn behouden. Dezelfde lijst staat bij elk bericht van een antwoord dat in meerdere delen is verzonden. Altijd een array, leeg voor inkomende berichten, berichten verzonden door mensen, automatische follow-ups en AI-antwoorden verzonden vóór 25 september 2026. |
faqs_used |
Dezelfde FAQ’s met hun vraag: elk item heeft id en question. question is null wanneer de FAQ sindsdien is verwijderd. |
Download een berichtbijlage
POST /chat-exports/media/download-url
Geeft je een nieuwe downloadlink voor het bestand dat aan een bericht is gekoppeld: een afbeelding, spraakbericht, video of document. De link werkt gedurende 1 uur. Gebruik deze wanneer je bijlagen ergens anders wilt opslaan (bijvoorbeeld bij het archiveren van cv’s of spraakberichten die een contactpersoon heeft gestuurd), of wanneer de media_url op een bericht of een New Message webhook niet meer opent.
Om berichten met bijlagen te vinden, kun je de berichten van een contactpersoon opvragen met filter=media. De id van elk bericht en de ID van de contactpersoon vormen samen de messagePath.
| Body-veld | Verplicht | Beschrijving |
|---|---|---|
messagePath |
Ja | Welk bericht, in de vorm 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"]
Antwoord (200 OK):
{
"success": true,
"data": {
"url": "https://storage.googleapis.com/...",
"expiresInMs": 3600000
}
}
| Veld | Beschrijving |
|---|---|
data.url |
De downloadlink. Haal het bestand direct op via deze link, er is geen API-sleutel nodig. |
data.expiresInMs |
Hoe lang de link werkt, in milliseconden (3600000 = 1 uur). Roep het eindpunt opnieuw aan voor een nieuwe link. |
| Status | Wanneer |
|---|---|
400 |
messagePath ontbreekt of is niet in de contacts/{contactId}/messages/{messageId} vorm, of het bericht heeft geen bijlage die op deze manier kan worden gedownload. Sommige oudere bijlagen worden opgeslagen bij de kanaalaanbieder en kunnen niet opnieuw worden uitgegeven, en een gedeelde Instagram-reel of -post is een link naar Instagram in plaats van een bestand. |
403 |
De contactpersoon behoort niet tot jouw account. |
404 |
Er bestaat geen bericht met dat ID bij die contactpersoon. |
Gebruik je een AI-client via MCP? Dezelfde actie is beschikbaar als de
get_chat_media_download_url-tool.
Chatsessies weergeven
Een chatsessie is één gespreksvenster met een contactpersoon. Het wordt geopend bij het eerste inkomende bericht wanneer er geen sessie openstaat en wordt automatisch gesloten 48 uur na het laatste inkomende bericht van de contactpersoon (elk nieuw inkomend bericht verschuift de sluiting met nog eens 48 uur). Wanneer de AI een chat afsluit, wordt de sessie niet gesloten; het activeert alleen de webhook ‘Chat afgesloten’. Sessies zijn de manier waarop u een lange geschiedenis opdeelt in leesbare gesprekken in plaats van één eindeloze lijst.
Recente sessies voor alle contactpersonen
GET /chat-sessions/recent
Geeft de sessies terug die in de afgelopen X uur zijn gestart, nieuwste eerst, voor elke contactpersoon in het account.
| Query-parameter | Vereist | Beschrijving |
|---|---|---|
hours |
Ja | Hoeveel uur terug moet worden gekeken. Moet een positief geheel getal zijn. |
status |
Nee | Retourneer alleen sessies met deze status: ChatSessionOpened of ChatSessionClosed. |
limit |
Nee | Maximaal aantal sessies om te retourneren. Standaard 100, maximaal 100. |
includeMessages |
Nee | true voegt een messages array toe aan elke sessie. Standaard uitgeschakeld omdat het de respons veel groter maakt. |
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"])
Antwoord (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"
}
]
}
}
Alle sessies voor één contactpersoon
GET /chat-sessions/{contactId}
Geeft elke chatsessie voor één enkele contactpersoon terug. Dezelfde status, limit en includeMessages parameters als hierboven — hours is hier niet van toepassing.
cURL
curl "https://api.youraiconnector.com/v1/chat-sessions/contact123?limit=20" \
-H "X-API-Key: YOUR_API_KEY"
Antwoord (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"
}
]
}
}
Veldnamen voor sessie-ID verschillen tussen de twee endpoints. De lijst met recente sessies noemt het
session_id(het bevat ook de details van de contactpersoon, aangezien sessies van vele contactpersonen komen); de lijst per contactpersoon noemt hetid. Beide waarden zijn wat je doorgeeft als{sessionId}bij het ophalen van de volledige thread hieronder.
Wanneer includeMessages=true, krijgt elke sessie een messages array waarvan de items id, body, direction, timestamp, type, channel en status bevatten.
Een chatsessie-thread ophalen
GET /contacts/{contactId}/chat-sessions/{sessionId}/messages
Een chatsessie groepeert de berichten van een contactpersoon in één gespreksvenster. Dit eindpunt retourneert de volledige thread van een enkele sessie, oudste eerst, samen met de metagegevens van de sessie. U kunt sessie-ID’s voor een contactpersoon vinden via de chatsessie-eindpunten.
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"])
Antwoord (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
}
]
}
Het session-object rapporteert status (ChatSessionOpened indien actief, ChatSessionClosed zodra beëindigd), start_date_time, end_date_time en een voor mensen leesbare tag. De messages-array gebruikt dezelfde berichtvelden als het lijst-eindpunt.
Berichten bewerken, verwijderen en erop reageren
Deze endpoints wijzigen een bericht nadat het is verzonden. Twee ervan bereiken zowel het kanaal van de contactpersoon als je eigen kopie, dus lees de inleiding van de sectie voordat je ze implementeert — wat mogelijk is, hangt volledig af van het kanaal waarop de conversatie plaatsvindt.
Wat elk kanaal toestaat
| Actie | Kanalen die de kopie van de contactpersoon kunnen wijzigen | Tijdslimiet |
|---|---|---|
| Een verzonden bericht bewerken | Chatwidget, WhatsApp Web (alleen tekstberichten), Telegram, LinkedIn | Geen voor de chatwidget, 15 minuten op WhatsApp Web, 48 uur op Telegram, 60 minuten op LinkedIn |
| Voor iedereen verwijderen | Chatwidget, WhatsApp Web, Telegram, LinkedIn | 60 minuten op LinkedIn; de andere hebben geen gepubliceerde limiet |
| Reageren met een emoji | WhatsApp Web, Telegram | Geen |
Op elk ander kanaal — de WhatsApp Business API, SMS, Instagram, Messenger, e-mail, LINE, aangepaste kanalen — verwijdert een verwijdering het bericht nog steeds uit je inbox, maar behoudt de contactpersoon zijn kopie, en is bewerken of reageren helemaal niet mogelijk.
Een bericht bewerken
POST /contacts/{contactId}/messages/{messageId}/edit
Herschrijft een bericht dat je al hebt verzonden, op het apparaat van de contactpersoon en in jouw kopie.
| Veld | Verplicht | Beschrijving |
|---|---|---|
body |
Ja | De nieuwe berichttekst. Mag niet leeg zijn en niet langer dan het kanaal toestaat in één bericht (dezelfde limieten per kanaal als Verzenden via contact-ID; 4.096 wanneer het bericht geen kanaal heeft). |
In tegenstelling tot verwijderen, mislukt dit luidruchtig wanneer het kanaal weigert: je krijgt een 409 en je kopie blijft precies zoals de contactpersoon deze heeft, omdat het tonen van een bewerking die ze nooit hebben ontvangen de twee partijen uit de pas zou laten lopen. Het veld edit_reason vertelt je waarom — het bewerkingsvenster van het kanaal is gesloten, het kanaal is losgekoppeld, het bericht heeft een bijlage die het kanaal niet kan bewerken (media_not_editable: op WhatsApp Web kunnen alleen tekstberichten worden bewerkt, niet de tekst onder een foto, video of bestand), of er is iets anders misgegaan.
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"))
Antwoord (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"edited": true,
"edit_reason": "edit_dispatched"
}
Als het kanaal de bewerking niet accepteert, krijg je in plaats daarvan een 409 en is er niets gewijzigd:
{
"success": false,
"error": "The message could not be edited",
"edit_reason": "channel_disconnected"
}
Een bericht dat al is verwijderd, een kanaal dat helemaal niet kan bewerken, en een bericht dat te oud is voor zijn kanaal retourneren allemaal 400 — het verzoek bereikt het kanaal nooit.
Eén bericht verwijderen
DELETE /contacts/{contactId}/messages/{messageId}
Verwijdert het bericht uit je gesprek en, waar het kanaal dit toestaat, trekt ook de kopie van de contactpersoon in. Geen verzoektekst.
Dit antwoordt altijd met 200 wanneer het bericht bestond, zelfs als de kopie van de contactpersoon niet kon worden ingetrokken — jouw kopie is weg, dus een foutmelding zou misleidend zijn. Lees de drie velden in het antwoord om de gebruiker te vertellen wat er daadwerkelijk is gebeurd:
| Veld | Beschrijving |
|---|---|
revoke_supported |
Of dit kanaal überhaupt berichten kan intrekken. |
revoked |
Of de kopie op het apparaat van de contactpersoon is verwijderd. |
revoke_reason |
Waarom het niet is verwijderd, wanneer revoked false is — bijvoorbeeld revoke_window_closed of 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"])
Antwoord (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"revoke_supported": true,
"revoked": true,
"revoke_reason": "revoke_dispatched"
}
Verwijderde berichten worden niet uit de gespreksgeschiedenis verwijderd. Ze blijven in
GET /contacts/{contactId}/messagesstaan metis_deleted: trueen een legebodyenmedia_url.
Meerdere berichten tegelijk verwijderen
POST /contacts/{contactId}/messages/bulk-delete
Wist een reeks berichten alleen aan jouw kant. De inhoud en bijlagen worden geleegd, maar er wordt niets ingetrokken op het apparaat van de contactpersoon — om een bericht ook daar terug te halen, verwijder je het één voor één met het bovenstaande eindpunt voor losse berichten.
| Veld | Vereist | Beschrijving |
|---|---|---|
message_ids |
Ja | Een niet-lege array van bericht-ID’s, tot 500 per verzoek. messageIds wordt geaccepteerd als 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"])
Antwoord (200 OK):
{
"success": true,
"contact_id": "contact123",
"deleted": 2
}
Reageren op een bericht
POST /contacts/{contactId}/messages/{messageId}/react
Plaatst je eigen emoji-reactie op een bericht, of trekt deze in door een lege tekenreeks te sturen. De reacties van de contactpersoon zelf worden nooit aangepast.
| Veld | Vereist | Beschrijving |
|---|---|---|
emoji |
Ja | De emoji om mee te reageren, of "" om je reactie te verwijderen. Moet een enkele tekenreeks zijn zonder spaties, van maximaal 16 tekens. |
Net als bij bewerken mislukt dit in plaats van een reactie te tonen die de contactpersoon nooit heeft ontvangen, en de foutmelding vertelt je of het de moeite waard is om het opnieuw te proberen:
422— het kan nooit worden afgeleverd in dit gesprek: het kanaal ondersteunt geen reacties, het bericht heeft geen kanaal-ID, of de emoji valt buiten de set die het kanaal toestaat.409— het kanaal was tijdelijk onbereikbaar. Een nieuwe poging kan werken.
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"])
Antwoord (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"
}
]
}
De reactions array is de volledige set reacties die nu op het bericht staan, zowel die van jou als die van de contactpersoon. Bij een 409 of 422 wordt deze ongewijzigd geretourneerd, zodat een client die direct op basis hiervan rendert nooit een reactie toont die niet is afgeleverd.
Een bericht beoordelen of een ster geven
PATCH /contacts/{contactId}/messages/{messageId}
Geeft een bericht een duim omhoog of omlaag en/of markeert het als belangrijk met een ster. Dit is alleen administratie aan jouw kant — er wordt niets naar de contactpersoon verzonden.
| Veld | Vereist | Beschrijving |
|---|---|---|
score |
Nee | 1 duim omhoog, -1 duim omlaag, 0 wist de beoordeling. |
is_important |
Nee | true geeft het bericht een ster, false verwijdert de ster. Moet een echte boolean zijn, niet de string "true". |
Verstuur ten minste een van de twee, anders krijg je een 400. Alleen wat je verstuurt wordt geschreven, dus het toevoegen van een ster aan een bericht wist nooit de beoordeling en vice versa — en het antwoord bevat alleen de velden die je hebt verstuurd.
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},
)
Antwoord (200 OK):
{
"success": true,
"contact_id": "contact123",
"message_id": "msg_1",
"score": 1,
"is_important": true
}
Berichten als gelezen markeren
U kunt de ongelezen status wissen voor specifieke berichten of voor het hele gesprek.
Specifieke berichten als gelezen markeren
POST /contacts/{contactId}/messages/mark-read
Geef de ID’s door van de berichten die als gelezen moeten worden gemarkeerd.
| Veld | Vereist | Beschrijving |
|---|---|---|
message_ids |
Ja | Een niet-lege array van bericht-ID’s (maximaal 500 per verzoek). |
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"])
Antwoord (200 OK):
{
"success": true,
"contact_id": "contact123",
"marked_read": 2
}
De hele chat als gelezen markeren
POST /contacts/{contactId}/mark-read
Wist de ongelezen-badge voor het volledige gesprek van de contactpersoon in de inbox. Er is geen verzoektekst vereist.
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"])
Antwoord (200 OK):
{
"success": true,
"contact_id": "contact123"
}
Markeer de hele chat als ongelezen
POST /contacts/{contactId}/mark-unread
Plaatst de ongelezen-badge terug op het gesprek — handig wanneer iemand in je team een chat heeft geopend maar deze weer overdraagt. Er is geen aanvraagtekst vereist.
Dit is een vlag die alleen voor de inbox geldt: het verandert niet wanneer het gesprek voor het laatst is gelezen, dus er wordt geen leesbevestiging verstuurd naar de contactpersoon op kanalen die dit ondersteunen.
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts/contact123/mark-unread" \
-H "X-API-Key: YOUR_API_KEY"
Antwoord (200 OK):
{
"success": true,
"contact_id": "contact123"
}
Exporteer een gesprek
Exportbestanden geven je een volledig gesprek als een leesbaar transcript, in plaats van door berichten te bladeren. Elk export-eindpunt accepteert een filter van all (standaard), text, media of tool_use, overeenkomend met het filter op de berichtenlijst.
Exporteer de chat van één contactpersoon
GET /chat-exports/{contactId}
| Query-parameter | Vereist | Beschrijving |
|---|---|---|
format |
Nee | txt (standaard) retourneert een downloadlink naar een platte-teksttranscript. json retourneert de berichten als gestructureerde data in het antwoord. |
filter |
Nee | all (standaard), text, media of 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"])
Antwoord met 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
}
]
}
}
Met format=txt (de standaard), is data in plaats daarvan een downloadlink naar het gegenereerde transcriptbestand:
{
"success": true,
"data": "https://storage.googleapis.com/.../chat-export-contact123-....txt"
}
De downloadlink is tijdelijk. Haal het bestand op zodra je de link ontvangt in plaats van deze op te slaan — vraag een nieuwe export aan wanneer je het transcript opnieuw nodig hebt.
Exporteer elk recent gesprek
GET /chat-exports/recent
Exporteert de gesprekken van alle contacten die in de afgelopen X uur actief waren, in één aanroep.
| Query-parameter | Vereist | Beschrijving |
|---|---|---|
hours |
Ja | Hoeveel uur aan activiteit moet worden teruggekeken. Moet een positief geheel getal zijn. |
format |
Nee | json (standaard) retourneert één item per contact. txt retourneert één downloadbaar tekstbestand met elk gesprek erin. |
limit |
Nee | Maximaal aantal contacten om te exporteren. Standaard 50, maximum 100. |
filter |
Nee | all (standaard), text, media of tool_use. |
cURL
curl "https://api.youraiconnector.com/v1/chat-exports/recent?hours=24&limit=25" \
-H "X-API-Key: YOUR_API_KEY"
Antwoord (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..."
}
]
}
}
Met format=txt is het antwoord het tekstbestand zelf, verzonden als een download in plaats van JSON.
Deze ene aanroep haalt de volledige geschiedenis op van elk overeenkomend contact, dus houd
hoursenlimitbescheiden bij drukke accounts.
E-mail een transcript naar de contactpersoon
POST /chat-exports/{contactId}/email
Verstuurt de contactpersoon zijn eigen gespreksverslag per e-mail — de “e-mail mij deze chat”-flow, aangestuurd vanuit je eigen systeem.
| Veld | Vereist | Beschrijving |
|---|---|---|
recipient_email |
Nee | Waar het naartoe moet worden gestuurd. Standaard is dit het opgeslagen e-mailadres van de contactpersoon. |
via |
Nee | auto (standaard) kiest de beste route, transactional verstuurt het als een systeeme-mail, email_channel verstuurt het vanaf je verbonden e-mailkanaal. |
note |
Nee | Een korte regel van jou die boven het transcript wordt getoond. Maximaal 1000 tekens. |
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." }'
Antwoord (200 OK):
{
"success": true,
"data": {
"via": "transactional",
"recipientEmail": "jane@example.com",
"messageCount": 42,
"omittedCount": 0
}
}
omittedCount vertelt je hoeveel van de oudste berichten zijn weggelaten om de e-mail op een redelijke lengte te houden. Een 200 betekent dat het transcript is opgesteld en in de wachtrij is geplaatst voor verzending, niet dat het al in de inbox is aangekomen.
De AI voor één contact pauzeren of hervatten
PUT /contacts/{contactId}
Zet is_bot_active op false om te stoppen met het beantwoorden van één contact door de AI, en terug op true om het gesprek weer over te dragen. Dit is de overnameschakelaar die u wilt gebruiken wanneer een mens een gesprek overneemt: uitgaande berichten die u met de API verstuurt, worden nog steeds afgeleverd terwijl de bot is gepauzeerd.
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},
)
Antwoord
{
"success": true,
"contact_id": "contact123"
}
Pauzeren als onderdeel van het antwoord
Als een mens het overneemt door een antwoord te sturen, kunt u de bot in hetzelfde verzoek pauzeren in plaats van een tweede aanroep te doen. POST /contacts/{contactId}/send-message accepteert deze optionele vlaggen:
| Veld | Beschrijving |
|---|---|
pauseBot |
true pauzeert de AI voor dit contact wanneer het bericht wordt verzonden. |
clearIncompleteReply |
true verwijdert een halfvoltooid bot-antwoord zodat het daarna niet wordt hervat. |
human_reply |
true markeert het bericht als een antwoord van een teamgenoot en annuleert een antwoord dat de AI in de wachtrij had staan. Voor pauzeren is nog steeds pauseBot nodig. |
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
}'
Het antwoord bevat "botPaused": true wanneer de pauze is toegepast.
Een contact markeren als privé met
POST /contacts/bulk-flagpauzeert ook de bot voor hen. Zie Contacten voor de volledige lijst met velden.
Uw eigen inbox bouwen
Alles wat een inbox nodig heeft, staat op deze pagina en in Contacten:
| Wat je nodig hebt | Eindpunt |
|---|---|
| Gesprekken weergeven | GET /contacts |
| Een gesprek lezen | GET /contacts/{contactId}/messages |
| Chatsessies van een contact weergeven | GET /chat-sessions/{contactId} |
| Zien wat er onlangs is binnengekomen | GET /chat-sessions/recent |
| Eén chatsessie lezen | GET /contacts/{contactId}/chat-sessions/{sessionId}/messages |
| Een handmatig antwoord sturen | POST /contacts/{contactId}/send-message |
| Een zojuist verzonden antwoord corrigeren | POST /contacts/{contactId}/messages/{messageId}/edit |
| Een bericht verwijderen | DELETE /contacts/{contactId}/messages/{messageId} |
| Meerdere berichten wissen | POST /contacts/{contactId}/messages/bulk-delete |
| Reageren met een emoji | POST /contacts/{contactId}/messages/{messageId}/react |
| Een bericht beoordelen of een ster geven | PATCH /contacts/{contactId}/messages/{messageId} |
| Markeren als gelezen | POST /contacts/{contactId}/mark-read |
| Een chat teruggeven aan het team | POST /contacts/{contactId}/mark-unread |
| Een transcript exporteren | GET /chat-exports/{contactId} |
| De AI pauzeren of hervatten | PUT /contacts/{contactId} met is_bot_active |
Voor live-updates abonneert u zich op de New Message, Replies, Human Alerted en Chat Concluded gebeurtenissen met Webhooks in plaats van deze API op een timer te pollen.
Fouten in de Messages API
Bericht-endpoints retourneren de standaard fouten-envelop:
{
"success": false,
"error": "Contact not found"
}
| Status | Wanneer dit gebeurt op een bericht-eindpunt |
|---|---|
400 |
Een vereist veld ontbreekt of een parameter is ongeldig (foutieve limit, hours, filter, direction, status, een lege of te grote message_ids-array, een ongeldige cursor, een lege of te lange bewerkings-body, een score buiten -1/0/1, of een emoji met spaties of meer dan 16 tekens). Wordt ook geretourneerd wanneer een bericht helemaal niet kan worden bewerkt — het is verwijderd, het kanaal ondersteunt geen bewerkingen, of het bewerkingsvenster van dat kanaal is verstreken. |
404 |
De contactpersoon, chatsessie of een van de opgegeven bericht-ID’s is niet gevonden. |
409 |
Het kanaal accepteert de wijziging op dit moment niet. Er is niets geschreven: bij een bewerking vertelt edit_reason waarom; bij een reactie was het kanaal tijdelijk onbereikbaar en kan een nieuwe poging werken. |
422 |
De contactpersoon kan geen uitgaande berichten ontvangen (niet storen, privé, of een niet-ondersteund kanaal), of een reactie kan nooit worden afgeleverd in dit gesprek (reaction_reason zegt welke). |
De gedeelde codes die elk endpoint kan retourneren — 401, 403 (uw abonnement bevat geen API-toegang), 429 (snelheidslimiet) en 500 — worden vermeld met richtlijnen voor opnieuw proberen in Fouten & Paginering.