Contacts API
Een contactpersoon is een individu naar wie je berichten stuurt — hun naam, telefoonnummer, e-mailadres, kanaal, labels, aangepaste velden en de lijsten en campagnes waartoe ze behoren. Met de Contacts API kun je contactpersonen aanmaken, opzoeken, bijwerken, labelen, in bulk importeren en verwijderen, allemaal zonder het dashboard te gebruiken.
Alle paden op deze pagina zijn relatief ten opzichte van de basis-URL:
https://api.youraiconnector.com/v1
Dus /contacts betekent https://api.youraiconnector.com/v1/contacts.
Nieuw bij de API? Lees eerst API Access — hierin wordt uitgelegd hoe je je API-sleutel genereert, de drie manieren om te authenticeren, limieten voor het aantal verzoeken en de foutopmaak. Alles op deze pagina gaat ervan uit dat je al een werkende API-sleutel hebt.
Over contact-ID’s
Elke contactpersoon heeft een uniek ID. Het ID dat je terugkrijgt wanneer je een contactpersoon aanmaakt (in data.contactId) is hetzelfde ID dat je overal elders gebruikt — om die contactpersoon op te halen, bij te werken, te labelen, een bericht te sturen of te verwijderen. Sla het één keer op en hergebruik het.
Je hoeft geen contactpersoon aan te maken om het ID te krijgen. Je kunt er ook een opzoeken op telefoonnummer of e-mailadres (zie Get a contact), of door al je contactpersonen bladeren (zie List contacts). Elk van deze geeft hetzelfde ID terug.
Een contactpersoon aanmaken
POST /contacts
Voegt een nieuwe contactpersoon toe aan je account. Een telefoonnummer met landcode is vereist — alleen een e-mailadres is niet voldoende. Al het andere is optioneel.
Je kunt de nieuwe contactpersoon optioneel direct in een of meer lijsten plaatsen met listId (één lijst) of listIds (een array). Als beide worden verzonden, wint listIds.
Elk veld dat u verstuurt en dat geen van de standaard aanmaakvelden is die in de onderstaande tabel Contact aanmaken staan (phoneNumber, firstName, lastName, email, channel, is_bot_active, is_private, lead_profile, listId, listIds, custom_fields), wordt automatisch opgeslagen als een aangepast veld — een platte payload van een tool zoals Make of Zapier werkt dus zonder nesting. U kunt ook een expliciet custom_fields object doorgeven.
| Veld | Vereist | Beschrijving |
|---|---|---|
phoneNumber |
Ja | Het telefoonnummer van de contactpersoon, met landcode (bijv. +15551234567). |
firstName |
Nee | Voornaam. |
lastName |
Nee | Achternaam. |
email |
Nee | E-mailadres. |
channel |
Nee | Berichtkanaal. Een van whatsapp, sms, whatsapp_web. Standaard is whatsapp. |
is_bot_active |
Nee | Of de AI-assistent antwoordt op deze contactpersoon. Standaard is true. |
is_private |
Nee | Markeer de contactpersoon als privé. Wanneer true, is de AI-assistent voor hen uitgeschakeld. Standaard is false. |
lead_profile |
Nee | Vrije tekstnotities over de lead. |
listId |
Nee | Een enkel lijst-ID om de contactpersoon aan toe te voegen. |
listIds |
Nee | Een array van lijst-ID’s om de contactpersoon aan toe te voegen (heeft voorrang op listId). |
custom_fields |
Nee | Een object met je eigen sleutel/waarde-velden. Je kunt deze ook doorgeven als top-level sleutels. |
cURL
curl -X POST "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+15551234567",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"is_bot_active": true,
"listIds": ["list123", "list456"]
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/contacts", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
phoneNumber: "+15551234567",
firstName: "Jane",
lastName: "Smith",
email: "jane@example.com",
is_bot_active: true,
listIds: ["list123", "list456"],
}),
});
const data = await res.json();
console.log(data.data.contactId);
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/contacts",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"phoneNumber": "+15551234567",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"is_bot_active": True,
"listIds": ["list123", "list456"],
},
)
print(res.json()["data"]["contactId"])
Antwoord
{
"success": true,
"data": {
"message": "Successfully created new contact",
"contactId": "contact_abc123",
"listsAdded": ["list123", "list456"]
}
}
De ID van de nieuwe contactpersoon staat op data.contactId. De lijsten waaraan deze is toegevoegd, worden teruggegeven in data.listsAdded.
Er worden geen duplicaten aangemaakt. Als er al een contact met hetzelfde telefoonnummer bestaat, maakt de aanroep voor aanmaken deze niet aan en wordt deze ook niet geretourneerd. Het antwoord komt terug met HTTP-status
200en eenerror_codevan409in de body, dus vertak operror_codein plaats van op de HTTP-status:{ "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user." }Om met een bestaand contact te werken na een
error_codevan409, zoekt u het op met Een contact ophalen op telefoonnummer of e-mailadres —GET /contacts?phoneNumber=...— en hergebruikt u de ID die dit teruggeeft.
Gelijkwaardige WhatsApp-spellingwijzen tellen als hetzelfde nummer. Sommige landen hebben twee geldige spellingen voor dezelfde mobiele lijn en WhatsApp kan beide rapporteren: Mexico (
+52…en de verouderde+521…), Brazilië (met of zonder het negende cijfer) en Argentinië (met of zonder de9na+54). De dubbelcheck bij aanmaak enGET /contacts?phoneNumber=komt overeen met beide spellingen, dus u krijgt de bestaande contactpersoon terug, ongeacht de vorm die u verstuurt. Hetphone_numberdat op de contactpersoon is opgeslagen, wordt nooit overschreven.
Een contactpersoon opzoeken op telefoonnummer of e-mailadres
GET /contacts?phoneNumber=... of GET /contacts?email=...
Zoekt één contactpersoon op en retourneert het volledige, verrijkte contactobject — inclusief de lijsten, tags en campagnes opgelost naar { id, name }-paren, plus het laatst uitgewisselde bericht.
Geef ofwel phoneNumber (in internationaal formaat) ofwel email op. Als je geen van beide opgeeft, schakelt dit eindpunt over naar de modus Contactpersonen vermelden.
cURL
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?phoneNumber=%2B15551234567&apiKey=YOUR_API_KEY"
JavaScript
const phone = encodeURIComponent("+15551234567");
const res = await fetch(`https://api.youraiconnector.com/v1/contacts?phoneNumber=${phone}`, {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);
Python
import requests
res = requests.get(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"phoneNumber": "+15551234567"},
)
print(res.json()["contact"])
Antwoord
{
"success": true,
"contactId": "contact_abc123",
"contact": {
"id": "contact_abc123",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"phoneNumber": "+15551234567",
"channel": "whatsapp",
"isBotActive": true,
"isPrivate": false,
"doNotDisturb": false,
"lead_profile": null,
"avatarUrl": "https://example.com/photo.jpg",
"customFields": {},
"lists": [{ "id": "list123", "name": "VIP customers" }],
"tags": [{ "id": "tagHotLead", "name": "Hot lead" }],
"campaigns": [{ "id": "campaign789", "name": "Spring promo" }],
"currentCampaign": { "id": "campaign789", "name": "Spring promo" },
"lastMessage": {
"direction": "inbound",
"body": "Sounds good, thanks!",
"status": "received",
"timestamp": "2026-06-09T10:21:00.000Z"
}
}
}
De contact-ID wordt zowel op het hoogste niveau (contactId) als in het object (contact.id) geretourneerd. Als er geen overeenkomst is, ontvang je een 404 met { "success": false, "message": "Contact not found" }.
avatarUrlis de profielfoto van de contactpersoon, afkomstig van WhatsApp of Meta wanneer zij je een bericht sturen. Deze is alleen-lezen: je kunt deze niet instellen en isnullvoor contactpersonen die geen foto hebben of die je bereiken via een kanaal dat er geen deelt. Behandel de link als tijdelijk in plaats van deze op te slaan, aangezien sommige van deze fotolinks verlopen en automatisch worden vernieuwd. (In het onderstaande lijsteindpunt wordt dezelfde waardeavatar_urlgenoemd.)
Telefoonnummers in URL’s. Een
+-teken in een query-string moet URL-geëncodeerd zijn als%2B, anders wordt het gelezen als een spatie. De bovenstaande voorbeelden doen dit automatisch voor je.
Een contactpersoon ophalen op ID
GET /contacts/{contactId}
Wanneer je het ID van een contactpersoon al hebt, kun je deze direct ophalen. De vorm van het antwoord is identiek aan de bovenstaande opzoekopdracht.
cURL
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.contact);
Python
import requests
res = requests.get(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["contact"])
Een contact-ID dat niet bestaat in je account retourneert een 404.
Contactstatistieken ophalen
GET /contacts/{contactId}/stats
Geeft geaggregeerde berichtstatistieken terug voor één contact: totalen, AI- versus menselijke antwoorden, verbruikte credits en tijdstempels van het eerste/laatste bericht.
cURL
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.totalMessages, data.creditsUsed);
Python
import requests
res = requests.get(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/stats",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["totalMessages"], data["creditsUsed"])
Antwoord
{
"success": true,
"totalMessages": 48,
"sent": 21,
"received": 27,
"aiReplies": 18,
"humanReplies": 3,
"creditsUsed": 34,
"botMessageCount": 18,
"firstMessageAt": "2026-05-01T09:00:00.000Z",
"lastMessageAt": "2026-06-09T10:21:00.000Z"
}
botMessageCount is dezelfde AI-berichtenteller die de “reset”-knop in de app voor een contact op nul zet. creditsUsed is het lopende credittotaal voor dit contact, niet alleen de cijfers van dit antwoord. Een contact-ID die niet bestaat in uw account retourneert een 404.
Contactpersonen weergeven
GET /contacts
Roep GET /contacts aan zonder phoneNumber of email om door al je contactpersonen te bladeren, beginnend bij de nieuwste. Elke pagina retourneert compacte samenvattingen van contactpersonen (lijsten, tags en campagnes worden geretourneerd als ID-arrays in plaats van volledige objecten) en een next_cursor.
| Query-parameter | Beschrijving |
|---|---|
limit |
Paginagrootte. Standaard 50, maximaal 100. |
cursor |
De next_cursor-waarde van de vorige pagina. Laat deze weg op de eerste pagina. |
listId |
Optioneel. Retourneer alleen contactpersonen die tot deze lijst behoren. |
Om elke pagina te doorlopen: doe de eerste aanroep zonder cursor en blijf vervolgens de geretourneerde next_cursor doorgeven als cursor. Stop wanneer next_cursor gelijk is aan null — dat betekent dat er geen resultaten meer zijn.
cURL
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&apiKey=YOUR_API_KEY"
# next page:
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?limit=50&cursor=contact_abc123&apiKey=YOUR_API_KEY"
JavaScript
async function listAllContacts() {
const all = [];
let cursor = null;
do {
const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
const data = await res.json();
all.push(...data.contacts);
cursor = data.next_cursor;
} while (cursor);
return all;
}
Python
import requests
def list_all_contacts():
all_contacts = []
cursor = None
while True:
params = {"limit": 100}
if cursor:
params["cursor"] = cursor
res = requests.get(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
headers={"X-API-Key": "YOUR_API_KEY"},
params=params,
)
data = res.json()
all_contacts.extend(data["contacts"])
cursor = data["next_cursor"]
if not cursor:
break
return all_contacts
Antwoord
{
"success": true,
"contacts": [
{
"id": "contact_abc123",
"first_name": "Jane",
"last_name": "Smith",
"email": "jane@example.com",
"phone_number": "+15551234567",
"channel": "whatsapp",
"is_bot_active": true,
"is_private": false,
"do_not_disturb": false,
"avatar_url": "https://example.com/photo.jpg",
"custom_fields": {},
"created_at": "2026-06-01T09:00:00.000Z",
"list_ids": ["list123"],
"tag_ids": ["tagHotLead"],
"campaign_ids": ["campaign789"],
"current_campaign_id": "campaign789"
}
],
"next_cursor": "contact_abc123"
}
Let op: Filteren op een listId die niet bestaat in je account retourneert een 404. Een ongeldige cursor retourneert een 400.
Contacten tellen
GET /contacts/count
Geeft terug hoeveel contacten overeenkomen met een filter, plus een uitsplitsing per kanaal, zonder dat je er doorheen hoeft te bladeren. Dit is de juiste aanroep voor elke “hoeveel”-vraag — een dashboard-tegel, een automatisering of een vraag aan Champ. Alle filters zijn optioneel en het combineren van meerdere filters verkleint het aantal (een contact moet aan elk opgegeven filter voldoen).
| Query-parameter | Beschrijving |
|---|---|
agentId |
Alleen contacten toegewezen aan deze AI-agent. Gebruik none voor contacten zonder toegewezen agent (deze worden beantwoord door de standaardagent van het kanaal). |
channel |
Alleen contacten op dit kanaal, bijv. whatsapp, messenger, instagram, sms, email, chat_widget. |
tag |
Alleen contacten met deze tag, op basis van de naam van de tag (hoofdlettergevoeligheid maakt niet uit). Een tagnaam die je niet hebt, geeft een 404 terug. |
listId |
Alleen contacten op deze lijst. |
botActive |
true of false — alleen contacten waarvan de AI-assistent is ingeschakeld of uitgeschakeld. |
status |
Alleen contacten met deze status, bijv. Lead. |
rules |
Een URL-gecodeerd JSON-regels-object, met dezelfde vorm als een slimme lijst (zie De smart_rules vorm verderop). Kan niet worden gecombineerd met de andere filters. |
Stuur helemaal geen filter en je krijgt het totaal aantal contacten in je account.
cURL
# everything
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?apiKey=YOUR_API_KEY"
# only the contacts one agent handles on Messenger
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count?agentId=agent_xyz789&channel=messenger&apiKey=YOUR_API_KEY"
JavaScript
const url = new URL("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count");
url.searchParams.set("agentId", "agent_xyz789");
url.searchParams.set("channel", "messenger");
const res = await fetch(url, { headers: { "X-API-Key": "YOUR_API_KEY" } });
const data = await res.json();
console.log(data.total);
Python
import requests
res = requests.get(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/count",
headers={"X-API-Key": "YOUR_API_KEY"},
params={"agentId": "agent_xyz789", "channel": "messenger"},
)
data = res.json()
print(data["total"])
Antwoord
{
"success": true,
"total": 3423,
"by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
"filters": { "agentId": "agent_xyz789" }
}
by_channel splitst hetzelfde totaal per kanaal; contacten die niet op een kanaal staan, worden geteld onder none. filters geeft de toegepaste filters terug, zodat je kunt controleren of de aanroep deed wat je bedoelde.
Let op: Het verzenden van rules samen met een ander filter, of een rules-waarde die geen geldige JSON is, geeft een 400 terug. Een tagnaam of lijst-ID die niet bestaat in je account geeft een 404 terug.
Een contact bijwerken
PUT /contacts/{contactId}
Werkt een bestaand contact bij. Alleen de velden die je opneemt worden gewijzigd — laat alles weg wat je niet wilt aanpassen. Je moet ten minste één veld meesturen, anders krijg je een 400 (“Geen velden om bij te werken”).
| Veld | Beschrijving |
|---|---|
firstName |
Voornaam. |
lastName |
Achternaam. |
email |
E-mailadres. |
is_bot_active |
Of de AI-assistent op dit contact reageert. |
is_private |
Markeren als privé. Dit instellen op true schakelt ook de AI-assistent uit. |
do_not_disturb |
Pauzeer geautomatiseerde outreach naar dit contact. Stopt ook de AI met reageren. |
follow_ups_disabled |
Stop alle geautomatiseerde follow-ups voor dit contact (quick, cycle en cold-lead) terwijl de AI blijft reageren op berichten die zij sturen. Handig zodra iemand iets heeft gekocht. Blijft uitgeschakeld totdat je het terugzet op false. |
lead_profile |
Vrije tekst voor leadnotities. |
custom_fields |
Een object met aangepaste velden. Samengevoegd per sleutel — alleen de sleutels die je verstuurt worden geschreven, de rest van de bestaande aangepaste velden blijft behouden. Je kunt ook aangepaste veldsleutels doorgeven op het hoogste niveau. |
cURL
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "firstName": "Jane", "do_not_disturb": true }'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
method: "PUT",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ firstName: "Jane", do_not_disturb: true }),
});
const data = await res.json();
console.log(data.message);
Python
import requests
res = requests.put(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"firstName": "Jane", "do_not_disturb": True},
)
print(res.json()["message"])
Antwoord
{
"success": true,
"message": "Contact updated successfully"
}
Aangepaste velden worden samengevoegd, niet vervangen. Het versturen van
{ "custom_fields": { "tier": "gold" } }stelt alleentierin — alle andere aangepaste velden van het contact blijven precies zoals ze waren. Om een aangepast veld volledig te verwijderen voor alle contacten, gebruik Een aangepast veld verwijderen.
Tags toevoegen of verwijderen
POST /contacts/{contactId}/tags
Voegt tags toe aan en/of verwijdert tags van een enkel contact in één aanroep. Geef tag-ID’s door in addTagIds en removeTagIds. Ten minste één van de twee moet niet leeg zijn.
De tags moeten al bestaan in je account — maak ze eerst aan via het tags-eindpunt. Als het contact of een van de verwezen tags niet bestaat, krijg je een 404.
| Veld | Beschrijving |
|---|---|
addTagIds |
Array van tag-ID’s om toe te voegen aan de contactpersoon. |
removeTagIds |
Array van tag-ID’s om te verwijderen van de contactpersoon. |
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"] }'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
addTagIds: ["tagHotLead"],
removeTagIds: ["tagColdLead"],
}),
});
const data = await res.json();
console.log(data.added, data.removed);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/tags",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"addTagIds": ["tagHotLead"], "removeTagIds": ["tagColdLead"]},
)
data = res.json()
print(data["added"], data["removed"])
Antwoord
{
"success": true,
"contact_id": "contact_abc123",
"added": 1,
"removed": 1
}
Uw tagbibliotheek beheren
Deze endpoints beheren de tag zelf — het hernoemen of verwijderen ervan in uw account — in tegenstelling tot het toevoegen of verwijderen van een tag bij een contact (zie Tags toevoegen of verwijderen hierboven). Elke tag in uw account heeft een ID (tagId): degene die wordt getoond in de tagmanager van uw dashboard, en degene die wordt geretourneerd als data.tag_id wanneer u een tag aanmaakt met POST /tags en een JSON-body van { "name": "..." } (geen phoneNumber, email of contactId).
Een tag bijwerken
PUT /tags/{tagId}
Verzend alleen de velden die u wijzigt.
| Veld | Beschrijving |
|---|---|
name |
De naam van de tag. |
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagHotLead?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Hot lead (Q3)" }'
Antwoord
{ "success": true, "tag_id": "tagHotLead" }
Een tagId die niet bestaat in uw account retourneert een 404.
Een tag verwijderen
DELETE /tags/{tagId}
Verwijdert één tag op ID. Dit kan niet ongedaan worden gemaakt — contacten met de tag verliezen deze simpelweg. Het verwijderen van een tag die al weg is (of nooit heeft bestaan) retourneert 200 met deleted: 0 in plaats van een 404, aangezien er niets is om op te sommen.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"
Antwoord
{ "success": true, "deleted": 1 }
Meerdere tags tegelijk verwijderen
DELETE /tags
| Veld | Beschrijving |
|---|---|
tagIds |
Array van tag-ID’s om te verwijderen (max. 1000). |
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "tagIds": ["tagColdLead", "tagUnsubscribed"] }'
Antwoord
{ "success": true, "deleted": 2 }
ID’s die niet bestaan of bij een ander account horen, worden stilzwijgend overgeslagen en niet meegeteld in deleted.
Bulk een vlag instellen
POST /contacts/bulk-flag
Stelt één booleaanse vlag in voor veel contactpersonen tegelijk. Maximaal 500 contact-ID’s per verzoek. ID’s die niet bestaan in uw account worden overgeslagen en meegeteld in skipped.
| Veld | Beschrijving |
|---|---|
contactIds |
Array van contact-ID’s om bij te werken (max. 500). |
field |
Welke vlag moet worden ingesteld. Eén van bot_active (AI-assistent aan/uit), dnd (geautomatiseerde outreach pauzeren), spam, private. |
value |
De booleaanse waarde waarop de vlag moet worden ingesteld. |
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contactIds": ["contactId1", "contactId2"],
"field": "bot_active",
"value": false
}'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
contactIds: ["contactId1", "contactId2"],
field: "bot_active",
value: false,
}),
});
const data = await res.json();
console.log(data.updated, data.skipped);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-flag",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"contactIds": ["contactId1", "contactId2"],
"field": "bot_active",
"value": False,
},
)
data = res.json()
print(data["updated"], data["skipped"])
Antwoord
{
"success": true,
"updated": 2,
"skipped": 0
}
Bulk contactpersonen importeren
POST /contacts/import
Maakt tot 500 contacten in één aanroep vanuit een JSON-array. Elk record heeft een phone_number in internationaal formaat nodig; al het overige is optioneel. Records met ongeldige telefoonnummers of niet-ondersteunde kanalen worden overgeslagen (niet aangemaakt), en elk overgeslagen record wordt gerapporteerd met de index en de reden — zodat u alleen de fouten kunt herstellen en het opnieuw kunt proberen.
Telefoonnummers die al in uw account bestaan, worden standaard overgeslagen als duplicate. Stuur updateExisting: true om die contacten in plaats daarvan te bijwerken: de velden in het record overschrijven die van het contact (first_name, last_name, email, lead_profile en custom_fields worden sleutel voor sleutel samengevoegd), tags worden toegevoegd en het contact wordt toegevoegd aan listId. Kanaal, telefoonnummer en bot-vlaggen worden nooit gewijzigd bij een bestaand contact.
U kunt optioneel elk geïmporteerd (of bijgewerkt) contact toevoegen aan een lijst met listId, een defaultChannel instellen voor records die er geen specificeren, en records labelen met tags (labelnamen — ontbrekende labels worden aangemaakt, bestaande labels worden hoofdletterongevoelig gematcht).
Top-level velden
| Veld | Verplicht | Beschrijving |
|---|---|---|
contacts |
Ja | Array van contactrecords (max. 500). |
listId |
Nee | Lijst om elk geïmporteerd (en bijgewerkt) contact aan toe te voegen. Moet een lijst in uw account zijn. |
defaultChannel |
Nee | Kanaal toegepast op records die channel weglaten. Een van whatsapp, sms, whatsapp_web. Standaard whatsapp. |
updateExisting |
Nee | true om contacten bij te werken wiens telefoonnummer al bestaat in plaats van ze over te slaan als duplicate. Standaard false. |
Per-record velden
| Veld | Verplicht | Beschrijving |
|---|---|---|
phone_number |
Ja | Telefoonnummer in internationaal formaat (een + aan het begin wordt toegevoegd indien ontbrekend). |
first_name |
Nee | Voornaam. |
last_name |
Nee | Achternaam. |
email |
Nee | E-mailadres. |
channel |
Nee | Een van whatsapp, sms, whatsapp_web. Valt terug op defaultChannel. |
is_bot_active |
Nee | Of de AI-assistent antwoordt. Standaard true. |
is_private |
Nee | Markeren als privé. Standaard false. |
lead_profile |
Nee | Vrije tekst voor leadnotities. |
custom_fields |
Nee | Object van aangepaste veldsleutels en waarden. |
tags |
Nee | Array van labelnamen (een enkele "a; b" string werkt ook). Labels die niet bestaan worden aangemaakt; bestaande worden gematcht zonder hoofdlettergevoeligheid. Max. 25 per record. |
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{ "phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"] },
{ "phone_number": "+12025551235", "first_name": "Bob" }
],
"listId": "list123",
"defaultChannel": "whatsapp_web",
"updateExisting": true
}'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
contacts: [
{ phone_number: "+12025551234", first_name: "Ann", last_name: "Lee", tags: ["vip", "newsletter"] },
{ phone_number: "+12025551235", first_name: "Bob" },
],
listId: "list123",
defaultChannel: "whatsapp_web",
updateExisting: true,
}),
});
const data = await res.json();
console.log(`Imported ${data.imported}, updated ${data.updated}, skipped ${data.skipped.length}`);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"contacts": [
{"phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee", "tags": ["vip", "newsletter"]},
{"phone_number": "+12025551235", "first_name": "Bob"},
],
"listId": "list123",
"defaultChannel": "whatsapp_web",
"updateExisting": True,
},
)
data = res.json()
print(f"Imported {data['imported']}, updated {data['updated']}, skipped {len(data['skipped'])}")
Antwoord
{
"success": true,
"imported": 2,
"contact_ids": ["contact_abc123", "contact_def456"],
"updated": 0,
"updated_contact_ids": [],
"skipped": []
}
Als sommige records niet kunnen worden aangemaakt, verschijnen ze in skipped met de reden (hier zonder updateExisting, dus het bestaande nummer wordt overgeslagen):
{
"success": true,
"imported": 1,
"contact_ids": ["contact_abc123"],
"updated": 0,
"updated_contact_ids": [],
"skipped": [
{ "index": 1, "phone_number": "+12025551235", "reason": "duplicate" }
]
}
Met updateExisting: true rapporteert hetzelfde verzoek het bestaande contact onder updated / updated_contact_ids in plaats daarvan.
Mogelijke redenen voor overslaan: invalid_record, missing_phone_number, invalid_phone_number, invalid_channel, duplicate_in_request, duplicate, contact_limit_reached, create_failed.
Abonnementslimieten. Als de contactlimiet van uw abonnement dit aantal nieuwe contacten niet toestaat, wordt het volledige verzoek vooraf afgewezen met een
403. Als de limiet halverwege wordt bereikt, worden de resterende records geretourneerd als overgeslagen met redencontact_limit_reached.
Contacten importeren vanuit een CSV-bestand
Voor imports die groter zijn dan wat bulk import ondersteunt (tot ongeveer 50.000 rijen), kun je een asynchrone importtaak in de wachtrij plaatsen voor een CSV-bestand dat al in de opslag van je account staat, en vervolgens de status opvragen totdat deze is voltooid.
De import starten
POST /contacts/import-csv
| Veld | Vereist | Beschrijving |
|---|---|---|
csvStoragePath |
Ja | Opslagpad van het CSV-bestand, onder users/{your account id}/imports/, eindigend op .csv. |
listName |
Ja | Maakt (of hergebruikt) een lijst met deze naam en voegt elk geïmporteerd contact hieraan toe. |
existingListRefs |
Nee | Array van bestaande lijst-ID’s om elk geïmporteerd contact ook aan toe te voegen. |
defaultChannel |
Nee | Kanaal dat wordt toegepast op rijen waarvoor er geen is opgegeven. |
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"csvStoragePath": "users/abc123/imports/leads.csv",
"listName": "Webinar signups"
}'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
csvStoragePath: "users/abc123/imports/leads.csv",
listName: "Webinar signups",
}),
});
const data = await res.json();
console.log(data.job_id);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"csvStoragePath": "users/abc123/imports/leads.csv",
"listName": "Webinar signups",
},
)
job_id = res.json()["job_id"]
Antwoord (202 — de import staat in de wachtrij, maar is nog niet voltooid)
{
"success": true,
"job_id": "csvimp_abc123",
"status": "queued"
}
Het bestand in de opslag krijgen. Dit eindpunt start en volgt de importtaak; het accepteert zelf geen upload. Het CSV-bestand moet al op
csvStoragePathstaan voordat je dit aanroept — de CSV-importfunctie van het dashboard doet dit als eerste stap.
De importtaak pollen
GET /contacts/import-csv/{jobId}
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/import-csv/csvimp_abc123?apiKey=YOUR_API_KEY"
Antwoord
{
"success": true,
"job_id": "csvimp_abc123",
"status": "completed",
"imported": 812,
"updated": 0,
"skipped": 14,
"errors": [],
"error_message": null
}
status doorloopt queued → processing → completed, of failed met de reden in error_message. Een jobId die niet bestaat in je account retourneert een 404.
Contacten exporteren
Start een asynchrone CSV-export van je contacten en retourneert een taak die je kunt opvragen voor voltooiing.
Start de export
POST /contacts/export
| Veld | Verplicht | Beschrijving |
|---|---|---|
listId |
Nee | Exporteer alleen contacten die tot deze lijst behoren. |
contactIds |
Nee | Exporteer alleen deze specifieke contact-ID’s. |
Als je beide weglaat, worden alle contacten in je account geëxporteerd.
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "listId": "list123" }'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ listId: "list123" }),
});
const data = await res.json();
console.log(data.job_id);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"listId": "list123"},
)
job_id = res.json()["job_id"]
Antwoord (202 — de export staat in de wachtrij)
{
"success": true,
"job_id": "export_abc123",
"status": "queued"
}
De exporttaak opvragen
GET /contacts/export/{jobId}
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export/export_abc123?apiKey=YOUR_API_KEY"
Antwoord
{
"success": true,
"job_id": "export_abc123",
"status": "completed",
"export_id": "exp_xyz789",
"contact_count": 812,
"error_message": null
}
Zodra
status"completed"is, ontvang jeexport_idencontact_count. Het downloaden van het gegenereerde CSV-bestand gebeurt via de pagina Export van je dashboard.
Stuur een bericht naar een contact
POST /contacts/{contactId}/send-message
Verstuurt een bericht naar een bestaande contactpersoon via het kanaal dat deze al gebruikt. Het bericht wordt in de wachtrij geplaatst en op de achtergrond afgeleverd — het antwoord bevestigt dat het is geaccepteerd, niet dat het al is afgeleverd.
| Veld | Vereist | Beschrijving |
|---|---|---|
body |
Ja | De tekst van het te verzenden bericht. |
mediaUrl |
Nee | URL van een mediabestand om bij te voegen. |
mediaContentType |
Nee | MIME-type van de bijgevoegde media (bijv. image/jpeg). |
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "Hi! Your appointment is confirmed." }'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ body: "Hi! Your appointment is confirmed." }),
});
const data = await res.json();
console.log(data.messageId);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"body": "Hi! Your appointment is confirmed."},
)
print(res.json()["messageId"])
Antwoord
{
"success": true,
"messageId": "aB3dE5fG7hI9jK1lM2nO",
"contactId": "contact_abc123",
"channel": "whatsapp",
"message": "Message created successfully. Delivery is being processed."
}
Kun je nu niet verzenden? Als de contactpersoon ‘niet storen’ of de privémodus heeft ingeschakeld, of zich niet op een kanaal bevindt dat uitgaande berichten kan ontvangen, wordt het verzoek afgewezen met een
422en een verklarendeerror.
Voor verzending via telefoonnummer, Instagram-ID of een andere kanaalidentiteit in plaats van een contact-ID — en voor meer informatie over berichten in het algemeen — zie de Messages API.
Een AI-agent toewijzen aan een contactpersoon
POST /contacts/{contactId}/assign-agent
Verplaatst een bestaand gesprek naar een andere AI-agent, vanaf het volgende bericht. Dit is hetzelfde als AI-agent toewijzen in het menu van een chat, en dezelfde stap die de actie AI-agent of campagne toewijzen in Automatiseringen gebruikt.
| Veld | Verplicht | Beschrijving |
|---|---|---|
agentId |
Ja | De ID van de AI-agent die het moet overnemen, of null om de toewijzing te wissen zodat het gesprek teruggaat naar je team-inbox. |
triggerAIResponse |
Nee | true zorgt ervoor dat de nieuw toegewezen agent direct reageert op de laatste onbeantwoorde berichten van de contactpersoon. Standaard ingesteld op false. |
Wees voorzichtig met
triggerAIResponse: true— het stuurt het contact direct een bericht, dus gebruik het alleen wanneer je wilt dat ze nu een bericht ontvangen. Op Messenger en Instagram mislukt dat bericht als het contact meer dan 24 uur geleden voor het laatst contact met je heeft opgenomen.
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "agentId": "agent_xyz789" }'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ agentId: "agent_xyz789" }),
});
const data = await res.json();
console.log(data.data.agentId);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/assign-agent",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"agentId": "agent_xyz789"},
)
print(res.json()["data"]["agentId"])
Antwoord
{
"success": true,
"data": {
"contactId": "contact_abc123",
"agentId": "agent_xyz789",
"aiResponseTriggered": false
}
}
De agent moet tot hetzelfde account behoren als de contactpersoon; anders wordt het verzoek afgewezen met een
404of403. Vind agent-ID’s op de pagina AI-agents (de URL van elke agent eindigt op zijn ID).
Een AI-agent toewijzen aan vele contacten
POST /contacts/bulk-assign-agent
Verplaatst vele gesprekken naar een andere AI-agent in één aanroep — of wist de toewijzing voor allemaal met null. Het is puur een routeringswijziging: er wordt geen bericht verzonden en de agent antwoordt niemand. Elk contact krijgt simpelweg de nieuwe agent de volgende keer dat ze schrijven. (Daarom is er hier geen triggerAIResponse.)
| Veld | Verplicht | Beschrijving |
|---|---|---|
agentId |
Ja | De AI-agent die het moet overnemen, of null om de toewijzing te wissen. |
contactIds |
Eén van de drie | Maximaal 500 contact-ID’s om te verplaatsen. |
filter |
Eén van de drie | Kies de contacten op de server in plaats van ze op te sommen, nieuwste eerst. Gebruikt dezelfde sleutels als de filters van het tel-eindpunt: agentId (of none), channel, tag, listId, botActive, status. |
rules |
Eén van de drie | Een regels-object voor een slimme lijst — zie De smart_rules vorm. |
limit |
Nee | Hoeveel contacten er in deze aanroep moeten worden verplaatst wanneer je selecteert met filter of rules. 1 tot 500, standaard is 500. |
Verzend precies één van contactIds, filter of rules.
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agentId": "agent_xyz789",
"filter": { "agentId": "agent_abc123", "channel": "messenger" }
}'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
agentId: "agent_xyz789",
filter: { agentId: "agent_abc123", channel: "messenger" },
}),
});
const data = await res.json();
console.log(data.updated, data.remaining);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/bulk-assign-agent",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"agentId": "agent_xyz789",
"filter": {"agentId": "agent_abc123", "channel": "messenger"},
},
)
data = res.json()
print(data["updated"], data["remaining"])
Antwoord
{
"success": true,
"agentId": "agent_xyz789",
"matched": 3415,
"updated": 500,
"skipped": 0,
"remaining": 2915,
"filters": { "agentId": "agent_abc123" }
}
matched is hoeveel contacten de selectie in totaal heeft gevonden, updated hoeveel er door deze aanroep zijn verplaatst, skipped hoeveel van de ID’s die je hebt verzonden niet zijn gevonden in je account, en remaining hoeveel er nu nog overeenkomen nu deze aanroep is voltooid.
Iedereen verplaatsen. Omdat een aanroep maximaal 500 contacten verplaatst, kost een grote groep een paar aanroepen. Gebruik een filter dat niet langer overeenkomt met een contact zodra het is verplaatst — bijvoorbeeld filter: { "agentId": "agent_abc123" } tijdens het toewijzen aan agent_xyz789 — en herhaal exact dezelfde aanroep totdat remaining terugkomt als 0. Wanneer je in plaats daarvan contactIds doorgeeft, is remaining altijd 0.
Een contact toewijzen aan een afdeling
POST /contacts/{contactId}/department
“Wijs deze lead toe aan Sales” — plaatst een contact onder een benoemde afdeling en wijst deze standaard toe aan degene op die afdeling die momenteel de minste contacten heeft. Dit staat los van het toewijzen van een AI-agent: een afdeling beantwoordt “welk team is hiervan de eigenaar,” een agent beantwoordt “welke AI beantwoordt dit,” en het instellen van de een wist de ander nooit.
| Veld | Verplicht | Beschrijving |
|---|---|---|
department_id |
Ja | De afdeling waaronder het contact wordt opgeslagen. Geef null door om dit te wissen. |
hand_to_member |
Nee | Wijs het contact ook toe aan de persoon op die afdeling met de minste werklast. Standaard true. Wijst nooit een contact opnieuw toe dat al eigendom is van iemand anders. |
cURL
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "department_id": "dept_sales" }'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ department_id: "dept_sales" }),
});
const data = await res.json();
console.log(data.assigned_to);
Python
import requests
res = requests.post(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/department",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"department_id": "dept_sales"},
)
print(res.json()["assigned_to"])
Antwoord
{
"success": true,
"department_id": "dept_sales",
"assigned_to": "member_uid_123"
}
assigned_to is null wanneer het contact al eigendom was van iemand, of als je hand_to_member: false hebt doorgegeven.
Een contact koppelen via kanalen
“Ga verder op WhatsApp” (of sms) zoekt of maakt het contact van deze persoon aan op een ander telefoon-gebaseerd kanaal en koppelt de twee aan elkaar, zodat de rest van de app hen als dezelfde persoon herkent.
Koppelen aan een ander kanaal
POST /contacts/{contactId}/link-channel
| Veld | Vereist | Beschrijving |
|---|---|---|
channel |
Ja | Het kanaal om aan te koppelen. Een van whatsapp, whatsapp_web, sms. |
phoneNumber |
Nee | Telefoonnummer om te gebruiken op het nieuwe kanaal. Standaard wordt het eigen nummer van het broncontact gebruikt. |
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link-channel?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "channel": "sms" }'
Antwoord
{
"success": true,
"data": {
"contact_id": "contact_def456",
"person_id": "person_xyz789",
"created": true
}
}
created geeft aan of er een nieuw contact is aangemaakt voor het doel-kanaal of dat er een bestaand contact is gevonden en gekoppeld. Een tweede keer aanroepen is veilig — het retourneert hetzelfde contact_id met created: false in plaats van een duplicaat aan te maken.
Een 422 betekent dat het account deze koppeling momenteel niet kan uitvoeren: het contact bevindt zich al in die kanaalfamilie, heeft geen telefoonnummer om te gebruiken, of er is geen verbonden afzender voor het doelkanaal. Een 409 betekent dat de twee contacten al aan twee verschillende personen zijn gekoppeld — ontkoppel er eerst een.
De gekoppelde gesprekken van een contact weergeven
GET /contacts/{contactId}/linked
Retourneert de andere gesprekken die dezelfde persoon zijn als dit contact. Een niet-gekoppeld contact retourneert een lege array, geen 404 — “deze persoon heeft geen andere kanalen” is een normale status.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/linked?apiKey=YOUR_API_KEY"
Antwoord
{
"success": true,
"data": [
{
"contact_id": "contact_def456",
"channel": "sms",
"custom_channel": null,
"first_name": "Jane",
"last_name": "Smith",
"phone_number": "+15551234567",
"last_message": "Sounds good, thanks!",
"last_message_timestamp": "2026-06-09T10:21:00.000Z",
"linked_from": {
"contact_id": "contact_abc123",
"channel": "whatsapp",
"linked_at": "2026-06-01T09:00:00.000Z",
"reason": "continue_on_channel"
}
}
]
}
Een contact ontkoppelen
DELETE /contacts/{contactId}/link
Verwijdert dit contact eenzijdig van zijn persoon — alle andere contacten die nog aan die persoon zijn gekoppeld, behouden hun koppeling, dus het ontkoppelen van één van de drie heft de groep niet op.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link?apiKey=YOUR_API_KEY"
Antwoord
{ "success": true }
De profielfoto van een contact ophalen
POST /contacts/{contactId}/profile-pic
Haalt (en cachet) de WhatsApp- of Meta-profielfoto van het contact op aanvraag — dezelfde foto die wordt geretourneerd als avatarUrl bij Een contact ophalen, ververst.
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/profile-pic?apiKey=YOUR_API_KEY"
Antwoord
{
"success": true,
"avatar_url": "https://example.com/photo.jpg",
"cached": false
}
cached: true betekent dat de URL afkomstig is van een recente ophaalactie in plaats van een nieuwe provider-opzoeking — foto’s worden 7 dagen gecachet, en een contact waarvan de provider meldt dat er geen bereikbare foto is, wordt 24 uur lang als niet beschikbaar gecachet. Wanneer er geen foto is om op te halen, wordt avatar_url weggelaten en legt message uit waarom.
Contacten automatisch taggen met AI
Voert de tagregels van uw account uit over de volledige gespreksgeschiedenis van een of meer contacten en past tags toe (of verwijdert ze) precies zoals de realtime tagging die tijdens een livechat plaatsvindt — dezelfde regels, dezelfde creditkosten per tag.
Een uitvoering starten
POST /contacts/auto-tag
| Veld | Verplicht | Beschrijving |
|---|---|---|
scope |
Ja | "contacts" om specifieke contacten te taggen, of "agent" om elk gesprek te taggen dat momenteel door één AI-agent wordt afgehandeld. |
contact_ids |
Verplicht wanneer scope "contacts" is |
Array van contact-ID’s, 1 tot 500. |
agent_id |
Verplicht wanneer scope "agent" is |
De AI-agent wiens gesprekken moeten worden getagd. Wanneer scope "contacts" is, is dit optioneel en beperkt het alleen welke tagregels van de agent worden uitgevoerd. |
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "scope": "contacts", "contact_ids": ["contact_abc123", "contact_def456"] }'
Een enkel contact wordt inline uitgevoerd en retourneert het resultaat direct:
{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }
Twee of meer contacten (of scope: "agent") worden uitgevoerd als een achtergrondtaak en retourneren direct 202:
{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }
Een uitvoering pollen
GET /contacts/auto-tag/run
Retourneert de huidige (of meest recente) uitvoering van het account, zodat u de voortgang kunt pollen zonder zelf run_id bij te houden.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag/run?apiKey=YOUR_API_KEY"
Antwoord
{
"success": true,
"run": {
"run_id": "m1x2y3-a1b2c3d4",
"status": "running",
"total": 214,
"processed": 58,
"tagged_contacts": 12,
"tags_applied": 15,
"tags_removed": 2,
"credits_charged": 15
}
}
run is null wanneer het account er nog nooit een heeft gestart. status gaat van "running" naar "completed" of "failed".
Er kan per account slechts één bulkuitvoering tegelijkertijd actief zijn — het starten van een tweede terwijl er al een draait, retourneert 409 met error_code: "auto_tag_run_in_progress". Als de credits opraken bij een uitvoering voor één contact, wordt 402 met error_code: "insufficient_credits" geretourneerd; een bulkuitvoering stopt in plaats daarvan voortijdig en rapporteert in run hoe ver deze is gekomen.
Een contact verwijderen
DELETE /contacts/{contactId}
Verwijdert permanent één contact op basis van ID, samen met de berichtgeschiedenis. Dit kan niet ongedaan worden gemaakt. Gebruik Contacten verwijderen hieronder om meerdere contacten in één aanroep te verwijderen.
cURL
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123", {
method: "DELETE",
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.success);
Python
import requests
res = requests.delete(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(res.json()["success"])
Antwoord
{
"success": true
}
Een contact-ID die niet bestaat in uw account, of die bij een ander account hoort, retourneert een 404.
Contactpersonen verwijderen
DELETE /contacts
Verwijdert permanent een of meer contactpersonen op ID in één aanroep (maximaal 500 ID’s). ID’s die niet in je account bestaan, worden overgeslagen en meegeteld in skipped. Dit kan niet ongedaan worden gemaakt.
| Veld | Beschrijving |
|---|---|
contactIds |
Array van contact-ID’s om te verwijderen (max. 500). |
cURL
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "contactIds": ["contactId1", "contactId2"] }'
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts", {
method: "DELETE",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ contactIds: ["contactId1", "contactId2"] }),
});
const data = await res.json();
console.log(`Deleted ${data.deleted}, skipped ${data.skipped}`);
Python
import requests
res = requests.delete(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"contactIds": ["contactId1", "contactId2"]},
)
data = res.json()
print(f"Deleted {data['deleted']}, skipped {data['skipped']}")
Antwoord
{
"success": true,
"deleted": 2,
"skipped": 0
}
Een aangepast veld verwijderen
DELETE /contacts/custom-fields/{fieldKey}
Verwijdert één aangepaste veldsleutel van elke contactpersoon in uw account. Gebruik dit om op te schonen na het hernoemen of verwijderen van een aangepast veld. De sleutel mag alleen letters, cijfers, underscores en koppeltekens bevatten. Geeft aan hoeveel contactpersonen zijn bijgewerkt. Dit kan niet ongedaan worden gemaakt.
cURL
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh", {
method: "DELETE",
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(`Removed from ${data.updated} contacts`);
Python
import requests
res = requests.delete(
"<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/custom-fields/webinar_date_nh",
headers={"X-API-Key": "YOUR_API_KEY"},
)
print(f"Removed from {res.json()['updated']} contacts")
Antwoord
{
"success": true,
"updated": 42
}
Let op: Een veldsleutel met niet-ondersteunde tekens retourneert een 400.
Lijsten
Lijsten groeperen contacten. Een lijst is ofwel statisch (jij bepaalt wie erin staat) of slim (het lidmaatschap wordt berekend op basis van regels en automatisch up-to-date gehouden — zie Lijsten & Contacten organiseren).
| Veld | Beschrijving |
|---|---|
name |
Vereist bij aanmaak. Maximaal 100 tekens. |
status |
live (standaard) of draft. Kleine letters. |
contact_ids |
Array met contact-ID’s om aan de lijst toe te voegen. Alleen statische lijsten. |
type |
static (standaard) of smart. |
smart_rules |
De regelset — vereist wanneer type gelijk is aan smart. Zie hieronder. |
Een lijst aanmaken
POST /lists
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Hot leads (active)",
"type": "smart",
"smart_rules": {
"match": "all",
"conditions": [
{ "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
{ "field": "last_activity_at", "op": "within_last", "value": { "amount": 90, "unit": "days" } }
]
}
}'
Antwoord
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 3, "removed": 0, "total": 3 }
}
Een slimme lijst wordt inline geëvalueerd, in hetzelfde verzoek, dus evaluation vertelt je precies wie er uiteindelijk in terecht is gekomen. Bij een statische lijst is evaluation gelijk aan null.
Een lijst bijwerken
PUT /lists/{listId}
Verstuur alleen de velden die je wijzigt. Het wijzigen van smart_rules zorgt ervoor dat de lijst onmiddellijk opnieuw wordt geëvalueerd en hetzelfde evaluation object wordt geretourneerd.
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/list_abc123?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "smart_rules": { "match": "any", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead", "tagWebinar"] } ] } }'
Je kunt een lijst tussen de twee soorten schakelen:
- Statisch → slim: stuur
{ "type": "smart", "smart_rules": { … } }. De regels worden direct toegepast. - Slim → statisch: stuur
{ "type": "static" }. De regels worden verwijderd en iedereen die op de lijst staat, blijft erop staan.
De smart_rules vorm
{
"match": "all",
"conditions": [
{ "field": "tags", "op": "has_any", "value": ["tagHotLead"] },
{ "field": "channel", "op": "is_any", "value": ["whatsapp", "sms"] },
{ "field": "last_incoming_message_at", "op": "not_within_last", "value": { "amount": 7, "unit": "days" } },
{ "field": "created_at", "op": "after", "value": "2026-01-01" },
{ "field": "is_bot_active", "op": "is", "value": true },
{ "field": "email", "op": "is_set" },
{ "field": "custom_field", "key": "Plan", "op": "eq", "value": "pro" }
]
}
match—all(elke voorwaarde moet waar zijn) ofany(ten minste één).conditions— 1 tot 20 voorwaarden, elk maximaal 100 waarden, strings tot 200 tekens.
field |
op |
value |
|---|---|---|
tags |
has_any, has_all, has_none |
array van tag-ID’s |
lists |
in_any, not_in_any |
array van lijst-ID’s (alleen statische lijsten — een slimme lijst kan niet worden opgebouwd uit een andere slimme lijst) |
channel |
is_any, is_none |
array van kanalen |
status |
is_any, is_none |
array van contactstatussen |
created_at, last_activity_at, last_incoming_message_at, last_outgoing_message_at, first_ai_interaction_at, last_ai_interaction_at |
within_last, not_within_last |
{ "amount": 1–3650, "unit": "hours" | "days" } |
| dezelfde datumvelden | before, after |
ISO-datum ("2026-01-01", vergeleken als hele dagen) of volledige ISO-datum/tijd ("2026-01-01T14:30:00Z", vergeleken tot op het exacte moment) |
| dezelfde datumvelden | is_set, not_set |
— |
has_interacted_with_ai |
is |
true / false — true komt overeen met contacten die de AI ten minste één keer (ooit) een bericht heeft gestuurd |
is_bot_active, do_not_disturb, is_private, has_ever_responded |
is |
true / false |
email, phone_number, first_name, last_name |
is_set, not_set, contains, not_contains |
string voor de contains formulieren |
current_campaign_id, assigned_agent |
is_any, is_none, is_set, not_set |
array van ID’s voor de is_any / is_none formulieren |
custom_field (plus een key) |
eq, neq, contains, not_contains, is_set, not_set |
string voor de waarde-formulieren |
not_within_last komt ook overeen met contacten waarvoor de datum nooit is ingesteld (“meer dan N geleden, of nooit”), en tekstvergelijkingen negeren hoofdlettergebruik.
AI-betrokkenheid. has_interacted_with_ai is de lifetime-vlag: true voor elk contact waarnaar uw AI ten minste één bericht heeft verzonden, false voor alle anderen (inclusief contacten die alleen door uw team zijn beantwoord). Deze wordt gestempeld bij het eerste bericht van de AI aan een contact en wordt nooit gewist, dus het uitschakelen van AI-antwoorden voor het contact of het verplaatsen naar een andere campagne reset dit niet. Voor een periode — “de contacten die mijn AI deze maand heeft afgehandeld”, de gebruikelijke facturatievraag — gebruikt u in plaats daarvan het bereik last_ai_interaction_at:
{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }
Verwar beide niet met is_bot_active (de AI mag antwoorden, niet dat hij dat heeft gedaan) of has_ever_responded (het contact schreef terug, aan wie dan ook). Dezelfde twee stempels worden bij elk contact geretourneerd als first_ai_interaction_at / last_ai_interaction_at, en de gehele regelset werkt ook op GET /contacts?rules=, zodat u overeenkomsten kunt tellen zonder een lijst aan te maken.
Een regelset bekijken
POST /lists/preview
Telt en toont voorbeelden van de contacten die een regelset zou matchen, zonder iets aan te maken of te wijzigen. Gebruik dit om regels te controleren voordat je ze opslaat.
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/lists/preview?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "smart_rules": { "match": "all", "conditions": [ { "field": "tags", "op": "has_any", "value": ["tagHotLead"] } ] } }'
Antwoord
{
"success": true,
"count": 3,
"sample": [
{
"id": "contact_abc123",
"first_name": "Sofia",
"last_name": "Martinez",
"phone_number": "+31600000000",
"email": "sofia@example.com",
"channel": "whatsapp"
}
]
}
sample bevat maximaal 10 contacten, gesorteerd op meest recent actief.
Een slimme lijst nu opnieuw uitvoeren
POST /lists/{listId}/evaluate
Forceert een onmiddellijke herevaluatie (hetzelfde als wat Nu vernieuwen doet in het dashboard). Slimme lijsten worden al bijgewerkt wanneer een contact wijzigt, en elke 15 minuten voor op tijd gebaseerde regels, dus dit is alleen nodig wanneer je het resultaat nu meteen wilt hebben.
Antwoord
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 2, "removed": 1, "total": 4 }
}
evaluation.skipped: true betekent dat er al een andere evaluatie van dezelfde lijst bezig was en deze aanroep niets heeft gedaan.
Slimme lijsten accepteren geen handmatig toegevoegde leden
Lidmaatschaps-endpoints retourneren 409 met "This is a smart list — its members are computed from its rules. Edit the rules instead." wanneer de doellijst slim is. Dit geldt voor POST /contacts/lists, DELETE /contacts/lists, POST /contacts/lists/batch, contact_ids op POST /lists en PUT /lists/{listId}, en het kiezen van een slimme lijst als doel voor een CSV-import. Wijzig in plaats daarvan de regels.
Het aanroepen van POST /lists/{listId}/evaluate op een statische lijst is ook een 409 — deze heeft geen regels om uit te voeren.
Contacts API-fouten
Contact-endpoints retourneren de standaard fouten-envelop:
{
"success": false,
"error": "Contact not found"
}
Sommige endpoints bevatten ook error_code, wat meestal overeenkomt met de HTTP-status — de enige uitzondering is het geval van een dubbel contact hieronder, waarbij de HTTP-status 200 is en alleen error_code de 409 bevat. De codes die specifiek zijn voor contact-endpoints:
| Code | Wanneer dit gebeurt op een contact-eindpunt |
|---|---|
400 |
Ongeldig verzoek — een ontbrekend/ongeldig veld, lege body, ongeldige cursor, of meer dan 500 ID’s in een batch. |
402 |
Onvoldoende credits om een AI-tagging-run op één contact te voltooien (error_code: "insufficient_credits"). |
404 |
Het contact, de lijst of de tag is niet gevonden in uw account. |
409 |
Er bestaat al een contact met dat telefoonnummer (bij aanmaken). Geretourneerd als error_code in de body met een HTTP-status van 200, dus vertak hier op error_code. Ook geretourneerd wanneer een bulk auto-tag-run al bezig is (error_code: "auto_tag_run_in_progress"), of wanneer het koppelen van een contact aan een ander kanaal twee contacten zou samenvoegen die al aan twee verschillende personen zijn gekoppeld. |
422 |
Het contact kan momenteel geen bericht ontvangen (niet storen, privé, of niet-ondersteund kanaal). Op het kanaalkoppelings-eindpunt dekt dit ook het ontbreken van een telefoonnummer, een niet-ondersteunde kanaalkoppeling, of het ontbreken van een verbonden afzender voor het doelkanaal. |
Een 403 op een contact-endpoint kan ook duiden op een probleem met de contactlimiet of lijsttoestemming in plaats van toegang via het abonnement. De gedeelde codes die elk endpoint kan retourneren — 401, 403 (uw abonnement bevat geen API-toegang), 429 (snelheidslimiet) en 500 — staan vermeld met richtlijnen voor opnieuw proberen in Fouten & Paginering.
Volgende stappen
- Messages API — berichten verzenden op basis van kanaalidentiteit en gesprekken beheren.
- API-referentie — volledige lijst met endpoints, inclusief tags en lijsten.
- API-toegang — authenticatie, snelheidslimieten en foutafhandeling.