Contacts API
En kontakt är en enskild person som du skickar meddelanden till – deras namn, telefonnummer, e-post, kanal, taggar, anpassade fält samt de listor och kampanjer de tillhör. Contacts API låter dig skapa kontakter, söka upp dem, uppdatera dem, tagga dem, importera dem i bulk och ta bort dem, allt utan att använda kontrollpanelen.
Alla sökvägar på denna sida är relativa till bas-URL:en:
https://api.youraiconnector.com/v1
Så /contacts betyder https://api.youraiconnector.com/v1/contacts.
Ny med API:et? Läs API-åtkomst först – den täcker hur du genererar din API-nyckel, de tre sätten att autentisera, hastighetsbegränsningar och felformatet. Allt på denna sida förutsätter att du redan har en fungerande API-nyckel.
Om kontakt-ID:n
Varje kontakt har ett unikt ID. Det ID du får tillbaka när du skapar en kontakt (i data.contactId) är samma ID som du använder överallt annars – för att hämta, uppdatera, tagga, skicka ett meddelande till eller ta bort den kontakten. Spara det en gång och återanvänd det.
Du behöver inte skapa en kontakt för att få dess ID. Du kan också söka upp ett ID via telefonnummer eller e-post (se Hämta en kontakt), eller bläddra igenom alla dina kontakter (se Lista kontakter). Var och en av dessa returnerar samma ID.
Skapa en kontakt
POST /contacts
Lägger till en ny kontakt i ditt konto. Ett telefonnummer med landskod krävs – enbart e-post räcker inte. Allt annat är valfritt.
Du kan valfritt lägga till den nya kontakten direkt i en eller flera listor med listId (en enskild lista) eller listIds (en array). Om båda skickas, vinner listIds.
Alla fält du skickar som inte är ett av standardfälten för skapande som listas i tabellen Skapa en kontakt nedan (phoneNumber, firstName, lastName, email, channel, is_bot_active, is_private, lead_profile, listId, listIds, custom_fields) sparas automatiskt som ett anpassat fält — så en platt nyttolast från ett verktyg som Make eller Zapier fungerar utan nästling. Du kan också skicka ett explicit custom_fields-objekt.
| Fält | Krävs | Beskrivning |
|---|---|---|
phoneNumber |
Ja | Kontaktens telefonnummer, med landskod (t.ex. +15551234567). |
firstName |
Nej | Förnamn. |
lastName |
Nej | Efternamn. |
email |
Nej | E-postadress. |
channel |
Nej | Meddelandekanal. En av whatsapp, sms, whatsapp_web. Standard är whatsapp. |
is_bot_active |
Nej | Huruvida AI-assistenten svarar på denna kontakt. Standard är true. |
is_private |
Nej | Markera kontakten som privat. När true, är AI-assistenten avstängd för dem. Standard är false. |
lead_profile |
Nej | Fritextanteckningar om leadet. |
listId |
Nej | Ett enskilt list-ID att lägga till kontakten i. |
listIds |
Nej | En array av list-ID:n att lägga till kontakten i (har företräde framför listId). |
custom_fields |
Nej | Ett objekt med dina egna nyckel/värde-fält. Du kan även skicka dessa som nycklar på toppnivå. |
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"])
Svar
{
"success": true,
"data": {
"message": "Successfully created new contact",
"contactId": "contact_abc123",
"listsAdded": ["list123", "list456"]
}
}
Den nya kontaktens ID finns i data.contactId. Listorna den lades till i återspeglas i data.listsAdded.
Duplikat skapas inte. Om en kontakt med samma telefonnummer redan finns, skapar eller returnerar anropet för att skapa inte kontakten. Svaret kommer tillbaka med HTTP-status
200och enerror_codepå409i brödtexten, så förgrena baserat påerror_codesnarare än på HTTP-statusen:{ "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user." }För att arbeta med en befintlig kontakt efter en
error_codepå409, slå upp den med Hämta en kontakt via telefon eller e-post —GET /contacts?phoneNumber=...— och återanvänd ID:t som returneras.
Motsvarande WhatsApp-stavningar räknas som samma nummer. Vissa länder har två giltiga stavningar för samma mobilnummer och WhatsApp kan rapportera vilket som helst av dem: Mexiko (
+52…och det äldre+521…), Brasilien (med eller utan den nionde siffran) och Argentina (med eller utan9efter+54). Dubblettkontrollen vid skapande ochGET /contacts?phoneNumber=matchar mot båda stavningarna, så du får tillbaka den befintliga kontakten oavsett vilken form du skickar. Detphone_numbersom lagras på kontakten skrivs aldrig över.
Hämta en kontakt via telefon eller e-post
GET /contacts?phoneNumber=... eller GET /contacts?email=...
Slår upp en enskild kontakt och returnerar det fullständiga, berikade kontaktobjektet — inklusive dess listor, taggar och kampanjer upplösta till { id, name }-par, plus det senast utväxlade meddelandet.
Skicka antingen phoneNumber (i internationellt format) eller email. Om du inte skickar något av dem växlar samma slutpunkt istället till läget Lista kontakter.
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"])
Svar
{
"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"
}
}
}
Kontakt-ID:t returneras både på toppnivå (contactId) och inuti objektet (contact.id). Om inget matchar får du ett 404 med { "success": false, "message": "Contact not found" }.
avatarUrlär kontaktens profilfoto, hämtat från WhatsApp eller Meta när de skickar ett meddelande till dig. Det är skrivskyddat: du kan inte ställa in det, och det ärnullför kontakter som inte har något foto eller som når dig via en kanal som inte delar ett. Behandla länken som tillfällig istället för att lagra den, eftersom vissa av dessa fotolänkar löper ut och uppdateras automatiskt. (I list-slutpunkten nedan kallas samma värde föravatar_url.)
Telefonnummer i URL:er. Ett
+-tecken i en frågesträng måste vara URL-kodat som%2B, annars läses det som ett mellanslag. Exemplen ovan gör detta åt dig.
Hämta en kontakt med ID
GET /contacts/{contactId}
När du redan har en kontakts ID kan du hämta den direkt. Svarsformatet är identiskt med sökningen ovan.
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"])
Ett kontakt-ID som inte finns på ditt konto returnerar ett 404.
Hämta kontaktstatistik
GET /contacts/{contactId}/stats
Returnerar sammanställd meddelandestatistik för en kontakt: totaler, AI- kontra mänskliga svar, förbrukade krediter samt tidsstämplar för första och sista meddelandet.
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"])
Svar
{
"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 är samma AI-meddelanderäknare som “återställ”-knappen i appen för en kontakt nollställer. creditsUsed är den löpande kredit-summan för denna kontakt, inte bara siffrorna för detta svar. Ett kontakt-ID som inte finns på ditt konto returnerar ett 404.
Lista kontakter
GET /contacts
Anropa GET /contacts utan varken phoneNumber eller email för att bläddra igenom alla dina kontakter, med de nyaste först. Varje sida returnerar kompakta kontaktsammanfattningar (listor, taggar och kampanjer returneras som ID-arrayer istället för fullständiga objekt) och en next_cursor.
| Frågeparameter | Beskrivning |
|---|---|
limit |
Sidstorlek. Standard är 50, max 100. |
cursor |
next_cursor-värdet från föregående sida. Utelämna på första sidan. |
listId |
Valfritt. Returnera endast kontakter som tillhör denna lista. |
För att gå igenom varje sida: gör det första anropet utan en markör (cursor), och fortsätt sedan att skicka tillbaka det returnerade next_cursor-värdet som cursor. Stoppa när next_cursor är null — det betyder att det inte finns några fler resultat.
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
Svar
{
"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"
}
Obs: Filtrering med en listId som inte finns på ditt konto returnerar en 404. En ogiltig cursor returnerar en 400.
Räkna kontakter
GET /contacts/count
Returnerar hur många kontakter som matchar ett filter, plus en uppdelning per kanal, utan att behöva bläddra igenom dem. Detta är rätt anrop för alla “hur många”-frågor — en instrumentpanel, en automatisering eller när du frågar Champ. Alla filter är valfria, och att kombinera flera begränsar antalet (en kontakt måste matcha alla du skickar med).
| Frågeparameter | Beskrivning |
|---|---|
agentId |
Endast kontakter tilldelade denna AI-agent. Skicka none för kontakter utan tilldelad agent (dessa besvaras av kanalens standardagent). |
channel |
Endast kontakter på denna kanal, t.ex. whatsapp, messenger, instagram, sms, email, chat_widget. |
tag |
Endast kontakter med denna tagg, baserat på taggens namn (skiftlägesoberoende). Ett taggnamn du inte har returnerar 404. |
listId |
Endast kontakter på denna lista. |
botActive |
true eller false — endast kontakter vars AI-assistent är på eller av. |
status |
Endast kontakter med denna status, t.ex. Lead. |
rules |
Ett URL-kodat JSON-regelobjekt, med samma form som en smart lista (se Formen för smart_rules längre ner). Kan inte kombineras med de andra filtren. |
Skicka inget filter alls så får du det totala antalet kontakter på ditt konto.
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"])
Svar
{
"success": true,
"total": 3423,
"by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
"filters": { "agentId": "agent_xyz789" }
}
by_channel delar upp samma total per kanal; kontakter som inte finns på någon kanal räknas under none. filters återspeglar de filter som tillämpades, så att du kan kontrollera att anropet gjorde vad du avsåg.
Obs: Om du skickar rules tillsammans med något annat filter, eller ett rules-värde som inte är giltig JSON, returneras 400. Ett taggnamn eller list-ID som inte finns på ditt konto returnerar 404.
Uppdatera en kontakt
PUT /contacts/{contactId}
Uppdaterar en befintlig kontakt. Endast de fält du inkluderar ändras — utelämna allt du inte vill ändra. Du måste skicka minst ett fält, annars får du ett 400 (“Inga fält att uppdatera”).
| Fält | Beskrivning |
|---|---|
firstName |
Förnamn. |
lastName |
Efternamn. |
email |
E-postadress. |
is_bot_active |
Huruvida AI-assistenten svarar på denna kontakt. |
is_private |
Markera som privat. Att ställa in detta till true stänger även av AI-assistenten. |
do_not_disturb |
Pausa automatiserad kontakt med denna person. Stoppar även AI:n från att svara. |
follow_ups_disabled |
Stoppa alla automatiserade uppföljningar för denna kontakt (snabba, cykel och kalla leads) medan AI:n fortsätter att svara på meddelanden de skickar. Användbart när någon har köpt. Förblir avstängt tills du ställer in det tillbaka till false. |
lead_profile |
Fritextanteckningar om leadet. |
custom_fields |
Ett objekt med anpassade fält. Slås samman per nyckel — endast nycklarna du skickar skrivs, resten av de befintliga anpassade fälten behålls. Du kan även skicka nycklar för anpassade fält på toppnivå. |
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"])
Svar
{
"success": true,
"message": "Contact updated successfully"
}
Anpassade fält slås samman, de ersätts inte. Att skicka
{ "custom_fields": { "tier": "gold" } }sätter endasttier— alla andra anpassade fält på kontakten förblir precis som de var. För att ta bort ett anpassat fält helt från alla kontakter, använd Ta bort ett anpassat fält.
Lägg till eller ta bort taggar
POST /contacts/{contactId}/tags
Lägger till och/eller tar bort taggar på en enskild kontakt i ett anrop. Skicka tagg-ID:n i addTagIds och removeTagIds. Minst en av de två måste vara icke-tom.
Taggarna måste redan finnas på ditt konto — skapa dem först via tagg-slutpunkten. Om kontakten eller någon refererad tagg inte finns, får du ett 404.
| Fält | Beskrivning |
|---|---|
addTagIds |
Array med tagg-ID:n som ska läggas till kontakten. |
removeTagIds |
Array med tagg-ID:n som ska tas bort från kontakten. |
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"])
Svar
{
"success": true,
"contact_id": "contact_abc123",
"added": 1,
"removed": 1
}
Hantera ditt taggbibliotek
Dessa slutpunkter hanterar själva taggen — att byta namn på eller ta bort den från ditt konto — till skillnad från att lägga till eller ta bort en tagg på en enskild kontakt (se Lägg till eller ta bort taggar ovan). Varje tagg på ditt konto har ett ID (tagId): det som visas i din kontrollpanels tagghanterare, och det som returneras som data.tag_id när du skapar en tagg med POST /tags och en JSON-kropp med { "name": "..." } (inga phoneNumber, email eller contactId).
Uppdatera en tagg
PUT /tags/{tagId}
Skicka endast de fält du ändrar.
| Fält | Beskrivning |
|---|---|
name |
Taggens namn. |
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)" }'
Svar
{ "success": true, "tag_id": "tagHotLead" }
Ett tagId som inte finns på ditt konto returnerar ett 404.
Ta bort en tagg
DELETE /tags/{tagId}
Tar bort en tagg via ID. Detta kan inte ångras — kontakter som har taggen förlorar den helt enkelt. Att ta bort en tagg som redan är borta (eller aldrig har funnits) returnerar 200 med deleted: 0 istället för ett 404, eftersom det inte finns något att räkna upp.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"
Svar
{ "success": true, "deleted": 1 }
Ta bort flera taggar samtidigt
DELETE /tags
| Fält | Beskrivning |
|---|---|
tagIds |
Array med tagg-ID:n som ska tas bort (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"] }'
Svar
{ "success": true, "deleted": 2 }
ID:n som inte existerar, eller som tillhör ett annat konto, hoppas över tyst och räknas inte i deleted.
Ange flagga för flera kontakter
POST /contacts/bulk-flag
Anger en boolesk flagga för många kontakter samtidigt. Upp till 500 kontakt-ID:n per förfrågan. ID:n som inte finns på ditt konto hoppas över och räknas i skipped.
| Fält | Beskrivning |
|---|---|
contactIds |
Array med kontakt-ID:n som ska uppdateras (max 500). |
field |
Vilken flagga som ska anges. En av bot_active (AI-assistent på/av), dnd (pausa automatiserad kontakt), spam, private. |
value |
Det booleska värdet som flaggan ska sättas till. |
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"])
Svar
{
"success": true,
"updated": 2,
"skipped": 0
}
Massimportera kontakter
POST /contacts/import
Skapar upp till 500 kontakter i ett anrop från en JSON-array. Varje post kräver ett phone_number i internationellt format; allt annat är valfritt. Poster med ogiltiga telefonnummer eller kanaler som inte stöds hoppas över (skapas inte), och varje post som hoppas över rapporteras med sitt index och orsak — så att du bara kan åtgärda felen och försöka igen.
Telefonnummer som redan finns på ditt konto hoppas som standard över som duplicate. Skicka updateExisting: true för att istället uppdatera dessa kontakter: fälten som finns i posten skriver över kontaktens (first_name, last_name, email, lead_profile och custom_fields slås samman nyckel för nyckel), tags läggs till och kontakten läggs till i listId. Kanal, telefonnummer och bot-flaggor ändras aldrig på en befintlig kontakt.
Du kan valfritt lägga till varje importerad (eller uppdaterad) kontakt i en lista med listId, ange en defaultChannel för poster som inte anger en, och tagga poster med tags (taggnamn — saknade taggar skapas, befintliga matchas oberoende av skiftläge).
Fält på toppnivå
| Fält | Krävs | Beskrivning |
|---|---|---|
contacts |
Ja | Array med kontaktposter (max 500). |
listId |
Nej | Lista att lägga till varje importerad (och uppdaterad) kontakt i. Måste vara en lista på ditt konto. |
defaultChannel |
Nej | Kanal som tillämpas på poster som utelämnar channel. En av whatsapp, sms, whatsapp_web. Standard är whatsapp. |
updateExisting |
Nej | true för att uppdatera kontakter vars telefonnummer redan finns istället för att hoppa över dem som duplicate. Standard är false. |
Fält per post
| Fält | Krävs | Beskrivning |
|---|---|---|
phone_number |
Ja | Telefonnummer i internationellt format (ett inledande + läggs till om det saknas). |
first_name |
Nej | Förnamn. |
last_name |
Nej | Efternamn. |
email |
Nej | E-postadress. |
channel |
Nej | En av whatsapp, sms, whatsapp_web. Faller tillbaka på defaultChannel. |
is_bot_active |
Nej | Om AI-assistenten svarar. Standard är true. |
is_private |
Nej | Markera som privat. Standard är false. |
lead_profile |
Nej | Fritextanteckningar för lead. |
custom_fields |
Nej | Objekt med nycklar och värden för anpassade fält. |
tags |
Nej | Array med taggnamn (en enskild "a; b"-sträng fungerar också). Taggar som inte finns skapas; befintliga matchas utan att ta hänsyn till skiftläge. Max 25 per post. |
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'])}")
Svar
{
"success": true,
"imported": 2,
"contact_ids": ["contact_abc123", "contact_def456"],
"updated": 0,
"updated_contact_ids": [],
"skipped": []
}
Om vissa poster inte kan skapas visas de i skipped med orsaken (här utan updateExisting, så det befintliga numret hoppas över):
{
"success": true,
"imported": 1,
"contact_ids": ["contact_abc123"],
"updated": 0,
"updated_contact_ids": [],
"skipped": [
{ "index": 1, "phone_number": "+12025551235", "reason": "duplicate" }
]
}
Med updateExisting: true rapporterar samma begäran den befintliga kontakten under updated / updated_contact_ids istället.
Möjliga orsaker till att poster hoppas över: invalid_record, missing_phone_number, invalid_phone_number, invalid_channel, duplicate_in_request, duplicate, contact_limit_reached, create_failed.
Planbegränsningar. Om din plans kontaktgräns inte tillåter så här många nya kontakter, avvisas hela förfrågan direkt med ett
403. Om gränsen nås halvvägs, returneras de återstående posterna som hoppade över med orsakencontact_limit_reached.
Importera kontakter från en CSV-fil
För importer som är större än vad massimport stöder (upp till cirka 50 000 rader), köa ett asynkront importjobb mot en CSV-fil som redan finns i ditt kontos lagring, och polla sedan jobbet tills det är slutfört.
Starta importen
POST /contacts/import-csv
| Fält | Krävs | Beskrivning |
|---|---|---|
csvStoragePath |
Ja | Lagringssökväg för CSV-filen, under users/{your account id}/imports/, som slutar på .csv. |
listName |
Ja | Skapar (eller återanvänder) en lista med detta namn och lägger till varje importerad kontakt i den. |
existingListRefs |
Nej | Array med befintliga list-ID:n som varje importerad kontakt också ska läggas till i. |
defaultChannel |
Nej | Kanal som tillämpas på rader som inte anger någon. |
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"]
Svar (202 — importen är köad, inte färdigställd än)
{
"success": true,
"job_id": "csvimp_abc123",
"status": "queued"
}
Att få in filen i lagringen. Denna slutpunkt startar och spårar importjobbet; den accepterar inte en uppladdning i sig. CSV-filen måste redan finnas på
csvStoragePathinnan du anropar den — instrumentpanelens egen CSV-importör gör detta som sitt första steg.
Polla importjobbet
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"
Svar
{
"success": true,
"job_id": "csvimp_abc123",
"status": "completed",
"imported": 812,
"updated": 0,
"skipped": 14,
"errors": [],
"error_message": null
}
status rör sig genom queued → processing → completed, eller failed med orsaken i error_message. Ett jobId som inte finns på ditt konto returnerar ett 404.
Exportera kontakter
Startar en asynkron CSV-export av dina kontakter och returnerar ett jobb som du pollar för slutförande.
Starta exporten
POST /contacts/export
| Fält | Krävs | Beskrivning |
|---|---|---|
listId |
Nej | Exportera endast kontakter som tillhör denna lista. |
contactIds |
Nej | Exportera endast dessa specifika kontakt-ID:n. |
Om båda utelämnas exporteras varje kontakt på ditt konto.
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"]
Svar (202 — exporten ligger i kö)
{
"success": true,
"job_id": "export_abc123",
"status": "queued"
}
Fråga efter exportjobbets status
GET /contacts/export/{jobId}
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export/export_abc123?apiKey=YOUR_API_KEY"
Svar
{
"success": true,
"job_id": "export_abc123",
"status": "completed",
"export_id": "exp_xyz789",
"contact_count": 812,
"error_message": null
}
När
statusär"completed"får duexport_idochcontact_count. Nedladdning av den genererade CSV-filen sker från din kontrollpanels sida för exporter.
Skicka ett meddelande till en kontakt
POST /contacts/{contactId}/send-message
Skickar ett meddelande till en befintlig kontakt via den kanal de redan använder. Meddelandet läggs i kö och levereras i bakgrunden — svaret bekräftar att det har tagits emot, inte att det har levererats än.
| Fält | Krävs | Beskrivning |
|---|---|---|
body |
Ja | Texten i meddelandet som ska skickas. |
mediaUrl |
Nej | URL till en mediefil som ska bifogas. |
mediaContentType |
Nej | MIME-typ för den bifogade filen (t.ex. 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"])
Svar
{
"success": true,
"messageId": "aB3dE5fG7hI9jK1lM2nO",
"contactId": "contact_abc123",
"channel": "whatsapp",
"message": "Message created successfully. Delivery is being processed."
}
Kan du inte skicka just nu? Om kontakten har aktiverat stör ej-läge eller privat läge, eller inte befinner sig på en kanal som kan ta emot utgående meddelanden, avvisas begäran med en
422och en förklarandeerror.
För att skicka via telefonnummer, Instagram-ID eller annan kanalidentitet istället för ett kontakt-ID — och för mer information om meddelanden i allmänhet — se Messages API.
Tilldela en AI-agent till en kontakt
POST /contacts/{contactId}/assign-agent
Flyttar en befintlig konversation till en annan AI-agent, från och med nästa meddelande. Det är samma sak som Tilldela AI-agent i en chatts meny, och samma steg som åtgärden Tilldela AI-agent eller kampanj använder i Automatiseringar.
| Fält | Krävs | Beskrivning |
|---|---|---|
agentId |
Ja | ID för den AI-agent som ska ta över, eller null för att rensa tilldelningen så att konversationen går tillbaka till din team-inkorg. |
triggerAIResponse |
Nej | true gör att den nyligen tilldelade agenten svarar på kontaktens senaste obesvarade meddelanden direkt. Standardvärdet är false. |
Var försiktig med
triggerAIResponse: true— det skickar ett meddelande till kontakten direkt, så använd det bara när du vill att de ska kontaktas nu. På Messenger och Instagram misslyckas meddelandet om kontakten senast skrev till dig för mer än 24 timmar sedan.
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"])
Svar
{
"success": true,
"data": {
"contactId": "contact_abc123",
"agentId": "agent_xyz789",
"aiResponseTriggered": false
}
}
Agenten måste tillhöra samma konto som kontakten; annars avvisas begäran med ett
404eller403. Hitta agent-ID:n på sidan för AI-agenter (varje agents URL slutar med dess ID).
Tilldela en AI-agent till många kontakter
POST /contacts/bulk-assign-agent
Flyttar många konversationer till en annan AI-agent i ett anrop — eller rensar tilldelningen för alla med null. Det är en ren routingsändring: inget meddelande skickas och agenten svarar inte någon. Varje kontakt får helt enkelt den nya agenten nästa gång de skriver. (Det är därför det inte finns något triggerAIResponse här.)
| Fält | Krävs | Beskrivning |
|---|---|---|
agentId |
Ja | AI-agenten som ska ta över, eller null för att rensa tilldelningen. |
contactIds |
En av tre | Upp till 500 kontakt-ID:n att flytta. |
filter |
En av tre | Välj kontakterna på servern istället för att lista dem, de nyaste först. Använder samma nycklar som räkne-endpointens filter: agentId (eller none), channel, tag, listId, botActive, status. |
rules |
En av tre | Ett regelobjekt för smart lista — se Formen för smart_rules. |
limit |
Nej | Hur många kontakter som ska flyttas i detta anrop när du väljer med filter eller rules. 1 till 500, standard är 500. |
Skicka exakt en av contactIds, filter eller 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"])
Svar
{
"success": true,
"agentId": "agent_xyz789",
"matched": 3415,
"updated": 500,
"skipped": 0,
"remaining": 2915,
"filters": { "agentId": "agent_abc123" }
}
matched är hur många kontakter urvalet hittade totalt, updated hur många som flyttades av detta anrop, skipped hur många av de ID:n du skickade som inte hittades på ditt konto, och remaining hur många som fortfarande matchar nu när anropet är klart.
Flytta alla. Eftersom ett anrop flyttar högst 500 kontakter krävs några anrop för en stor grupp. Använd ett filter som slutar matcha en kontakt när den väl har flyttats — till exempel filter: { "agentId": "agent_abc123" } medan du tilldelar till agent_xyz789 — och upprepa exakt samma anrop tills remaining returneras som 0. När du skickar contactIds istället är remaining alltid 0.
Tilldela en kontakt till en avdelning
POST /contacts/{contactId}/department
“Tilldela detta lead till försäljningsavdelningen” — arkiverar en kontakt under en namngiven avdelning och ger den som standard till den person på avdelningen som för närvarande har färst kontakter. Detta är skilt från att tilldela en AI-agent: en avdelning svarar på “vilket team äger detta”, en agent svarar på “vilken AI svarar på detta”, och att ställa in den ena rensar aldrig den andra.
| Fält | Krävs | Beskrivning |
|---|---|---|
department_id |
Ja | Avdelningen som kontakten ska arkiveras under. Skicka null för att rensa den. |
hand_to_member |
Nej | Ge även kontakten till den person på avdelningen som har minst arbetsbelastning. Standardvärdet är true. Omplacerar aldrig en kontakt som någon redan äger. |
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"])
Svar
{
"success": true,
"department_id": "dept_sales",
"assigned_to": "member_uid_123"
}
assigned_to är null när kontakten redan ägdes av någon, eller om du skickade hand_to_member: false.
Länka en kontakt över kanaler
“Fortsätt på WhatsApp” (eller SMS) hittar eller skapar personens kontakt i en annan telefonbaserad kanal och länkar samman de två, så att resten av appen känner igen dem som samma person.
Länka till en annan kanal
POST /contacts/{contactId}/link-channel
| Fält | Krävs | Beskrivning |
|---|---|---|
channel |
Ja | Kanalen att länka till. En av whatsapp, whatsapp_web, sms. |
phoneNumber |
Nej | Telefonnummer som ska användas på den nya kanalen. Standard är källkontaktens eget nummer. |
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" }'
Svar
{
"success": true,
"data": {
"contact_id": "contact_def456",
"person_id": "person_xyz789",
"created": true
}
}
created anger om en ny kontakt skapades för målkanalen eller om en befintlig hittades och länkades. Det är säkert att anropa detta en andra gång — det returnerar samma contact_id med created: false istället för att skapa en dubblett.
Ett 422 innebär att kontot inte kan utföra denna länkning just nu: kontakten finns redan i den kanalfamiljen, den saknar telefonnummer att använda, eller så finns ingen ansluten avsändare för målkanalen. Ett 409 innebär att de två kontakterna redan är länkade till två olika personer — koppla bort en först.
Lista en kontakts länkade konversationer
GET /contacts/{contactId}/linked
Returnerar de andra konversationer som tillhör samma person som denna kontakt. En olänkad kontakt returnerar en tom array, inte ett 404 — “denna person har inga andra kanaler” är ett normalt tillstånd.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/linked?apiKey=YOUR_API_KEY"
Svar
{
"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"
}
}
]
}
Koppla bort en kontakt
DELETE /contacts/{contactId}/link
Tar bort denna kontakt från sin person, ensidigt — alla andra kontakter som fortfarande är länkade till den personen behåller sin länk, så att koppla bort en av tre upplöser inte gruppen.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link?apiKey=YOUR_API_KEY"
Svar
{ "success": true }
Hämta en kontakts profilbild
POST /contacts/{contactId}/profile-pic
Hämtar (och cachar) kontaktens WhatsApp- eller Meta-profilfoto på begäran — samma foto som returneras som avatarUrl vid Hämta en kontakt, uppdaterat.
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/profile-pic?apiKey=YOUR_API_KEY"
Svar
{
"success": true,
"avatar_url": "https://example.com/photo.jpg",
"cached": false
}
cached: true innebär att URL:en kom från en nyligen utförd hämtning snarare än en färsk sökning hos leverantören — bilder cachas i 7 dagar, och en kontakt som leverantören rapporterar saknar tillgängligt foto cachas som otillgänglig i 24 timmar. När det inte finns någon bild att hämta utelämnas avatar_url och message förklarar varför.
Tagga kontakter automatiskt med AI
Kör kontots taggningsregler över en eller flera kontakters fullständiga konversationshistorik och lägger till (eller tar bort) taggar på exakt samma sätt som realtidstaggningsfunktionen som körs under en livechatt — samma regler, samma kreditkostnad per tagg.
Starta en körning
POST /contacts/auto-tag
| Fält | Krävs | Beskrivning |
|---|---|---|
scope |
Ja | "contacts" för att tagga specifika kontakter, eller "agent" för att tagga varje konversation som för närvarande hanteras av en AI-agent. |
contact_ids |
Krävs när scope är "contacts" |
Array av kontakt-ID:n, 1 till 500. |
agent_id |
Krävs när scope är "agent" |
AI-agenten vars konversationer ska taggas. När scope är "contacts" är detta valfritt och begränsar bara vilka av agentens taggningsregler som körs. |
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"] }'
En enskild kontakt körs inline och returnerar resultatet direkt:
{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }
Två eller fler kontakter (eller scope: "agent") körs som ett bakgrundsjobb och returnerar 202 omedelbart:
{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }
Fråga efter status för en körning
GET /contacts/auto-tag/run
Returnerar kontots nuvarande (eller senaste) körning, så att du kan kontrollera förloppet utan att själv behöva spåra run_id.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag/run?apiKey=YOUR_API_KEY"
Svar
{
"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 är null när kontot aldrig har startat en körning. status flyttas från "running" till "completed" eller "failed".
Endast en masskörning kan vara igång per konto åt gången — att starta en andra körning medan en annan pågår returnerar 409 med error_code: "auto_tag_run_in_progress". Om krediter tar slut vid en körning för en enskild kontakt returneras 402 med error_code: "insufficient_credits"; en masskörning stoppar istället sig själv i förtid och rapporterar hur långt den kom i run.
Ta bort en kontakt
DELETE /contacts/{contactId}
Tar permanent bort en kontakt via ID, tillsammans med dess meddelandehistorik. Detta kan inte ångras. För att ta bort flera kontakter i ett enda anrop, använd Ta bort kontakter nedan.
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"])
Svar
{
"success": true
}
Ett kontakt-ID som inte finns på ditt konto, eller som tillhör ett annat konto, returnerar ett 404.
Ta bort kontakter
DELETE /contacts
Tar permanent bort en eller flera kontakter via ID i ett enda anrop (upp till 500 ID:n). ID:n som inte finns på ditt konto hoppas över och räknas i skipped. Detta kan inte ångras.
| Fält | Beskrivning |
|---|---|
contactIds |
Array med kontakt-ID:n som ska tas bort (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']}")
Svar
{
"success": true,
"deleted": 2,
"skipped": 0
}
Ta bort ett anpassat fält
DELETE /contacts/custom-fields/{fieldKey}
Tar bort en anpassad fältnyckel från varje kontakt på ditt konto. Använd detta för att städa upp efter att ha döpt om eller tagit bort ett anpassat fält. Nyckeln får endast innehålla bokstäver, siffror, understreck och bindestreck. Returnerar hur många kontakter som uppdaterades. Detta kan inte ångras.
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")
Svar
{
"success": true,
"updated": 42
}
Obs: En fältnyckel med tecken som inte stöds returnerar en 400.
Listor
Listor grupperar kontakter. En lista är antingen statisk (du bestämmer vem som finns på den) eller smart (medlemskap beräknas utifrån regler och hålls automatiskt uppdaterat — se Organisera listor & kontakter).
| Fält | Beskrivning |
|---|---|
name |
Krävs vid skapande. Upp till 100 tecken. |
status |
live (standard) eller draft. Gemener. |
contact_ids |
Array med kontakt-ID:n att lägga till i listan. Endast statiska listor. |
type |
static (standard) eller smart. |
smart_rules |
Regeluppsättningen — krävs när type är smart. Se nedan. |
Skapa en lista
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" } }
]
}
}'
Svar
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 3, "removed": 0, "total": 3 }
}
En smart lista utvärderas inline, i samma anrop, så evaluation visar exakt vilka som hamnade på den. För en statisk lista är evaluation null.
Uppdatera en lista
PUT /lists/{listId}
Skicka endast de fält du ändrar. Om du ändrar smart_rules utvärderas listan omedelbart på nytt och returnerar samma evaluation-objekt.
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"] } ] } }'
Du kan växla en lista mellan de två typerna:
- Statisk → smart: skicka
{ "type": "smart", "smart_rules": { … } }. Reglerna tar över omedelbart. - Smart → statisk: skicka
{ "type": "static" }. Reglerna tas bort och de som finns på listan stannar kvar.
Strukturen för smart_rules
{
"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(alla villkor måste vara sanna) ellerany(minst ett).conditions— 1 till 20 villkor, varje med högst 100 värden, strängar på upp till 200 tecken.
field |
op |
value |
|---|---|---|
tags |
has_any, has_all, has_none |
matris med tagg-ID:n |
lists |
in_any, not_in_any |
matris med list-ID:n (endast statiska listor — en smart lista kan inte byggas från en annan smart lista) |
channel |
is_any, is_none |
matris med kanaler |
status |
is_any, is_none |
matris med kontaktstatusar |
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" } |
| samma datumfält | before, after |
ISO-datum ("2026-01-01", jämförs som hela dagar) eller fullständigt ISO-datum/tid ("2026-01-01T14:30:00Z", jämförs med det exakta ögonblicket) |
| samma datumfält | is_set, not_set |
— |
has_interacted_with_ai |
is |
true / false — true matchar kontakter som AI:n har skickat meddelanden till minst en gång (någonsin) |
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 |
sträng för contains-formulären |
current_campaign_id, assigned_agent |
is_any, is_none, is_set, not_set |
matris med ID:n för is_any / is_none-formulären |
custom_field (plus ett key) |
eq, neq, contains, not_contains, is_set, not_set |
sträng för värdeformulären |
not_within_last matchar även kontakter där datumet aldrig har angetts (“mer än N sedan, eller aldrig”), och textjämförelser ignorerar skiftläge.
AI-engagemang. has_interacted_with_ai är livstidsflaggan: true för varje kontakt som din AI har skickat minst ett meddelande till, false för alla andra (inklusive kontakter som bara ditt team någonsin har svarat). Den stämplas vid AI:ns första meddelande till en kontakt och rensas aldrig, så att stänga av AI-svar för kontakten eller flytta dem till en annan kampanj återställer den inte. För en period — “kontakterna min AI hanterade denna månad”, den vanliga faktureringsfrågan — använd istället intervallet last_ai_interaction_at:
{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }
Blanda inte ihop någon av dem med is_bot_active (AI:n får svara, inte att den har gjort det) eller has_ever_responded (kontakten svarade, till vem som helst). Samma två stämplar returneras för varje kontakt som first_ai_interaction_at / last_ai_interaction_at, och hela regeluppsättningen fungerar även på GET /contacts?rules=, så du kan räkna matchningar utan att skapa en lista.
Förhandsgranska en regeluppsättning
POST /lists/preview
Räknar och visar exempel på de kontakter som en regeluppsättning skulle matcha, utan att skapa eller ändra någonting. Använd detta för att kontrollera regler innan du sparar dem.
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"] } ] } }'
Svar
{
"success": true,
"count": 3,
"sample": [
{
"id": "contact_abc123",
"first_name": "Sofia",
"last_name": "Martinez",
"phone_number": "+31600000000",
"email": "sofia@example.com",
"channel": "whatsapp"
}
]
}
sample innehåller upp till 10 kontakter, sorterade efter senast aktiva först.
Kör om en smart lista nu
POST /lists/{listId}/evaluate
Tvingar fram en omedelbar omvärdering (samma sak som Uppdatera nu gör i kontrollpanelen). Smarta listor uppdateras redan när en kontakt ändras, samt var 15:e minut för tidsbaserade regler, så detta behövs bara när du vill ha resultatet direkt.
Svar
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 2, "removed": 1, "total": 4 }
}
evaluation.skipped: true innebär att en annan utvärdering av samma lista redan kördes och att detta anrop inte gjorde någonting.
Smarta listor tillåter inte manuellt tillagda medlemmar
Medlemskaps-endpoints returnerar 409 med "This is a smart list — its members are computed from its rules. Edit the rules instead." när mållistan är smart. Detta omfattar POST /contacts/lists, DELETE /contacts/lists, POST /contacts/lists/batch, contact_ids på POST /lists och PUT /lists/{listId}, samt att välja en smart lista som mål för CSV-import. Ändra reglerna istället.
Att anropa POST /lists/{listId}/evaluate på en statisk lista är också ett 409 — den har inga regler att köra.
Fel i Contacts API
Kontakt-endpoints returnerar standardfel-kuvertet:
{
"success": false,
"error": "Contact not found"
}
Vissa slutpunkter inkluderar även error_code, vilket vanligtvis matchar HTTP-statusen — det enda undantaget är fallet med dubblettkontakt nedan, där HTTP-statusen är 200 och endast error_code bär på 409. Koderna som är specifika för kontaktslutpunkter:
| Kod | När det inträffar på en kontakt-endpoint |
|---|---|
400 |
Felaktig förfrågan — ett saknat/ogiltigt fält, tom brödtext, felaktig markör eller över 500 ID:n i en batch. |
402 |
Inte tillräckligt med krediter för att slutföra en AI-taggningskörning på en kontakt (error_code: "insufficient_credits"). |
404 |
Kontakten, listan eller taggen hittades inte på ditt konto. |
409 |
En kontakt med det telefonnumret finns redan (vid skapande). Returneras som error_code i brödtexten med en HTTP-status på 200, så förgrena på error_code här. Returneras även när en automatisk mass-taggningskörning redan pågår (error_code: "auto_tag_run_in_progress"), eller när länkning av en kontakt till en annan kanal skulle slå samman två kontakter som redan är länkade till två olika personer. |
422 |
Kontakten kan inte ta emot ett meddelande just nu (stör ej, privat eller kanal som inte stöds). På endpointen för kanallänkning täcker det även inget telefonnummer, en parkoppling av kanal som inte stöds, eller ingen ansluten avsändare för målkanalen. |
Ett 403 på en kontaktslutpunkt kan också innebära ett problem med kontaktgräns eller listbehörighet snarare än abonnemangsåtkomst. De delade koderna som varje slutpunkt kan returnera — 401, 403 (ditt abonnemang inkluderar inte API-åtkomst), 429 (hastighetsbegränsning) och 500 — listas med vägledning för återförsök i Fel & Sidnumrering.
Nästa steg
- Messages API — skicka meddelanden via kanalidentitet och hantera konversationer.
- API-referens — fullständig lista över endpoints, inklusive taggar och listor.
- API-åtkomst — autentisering, hastighetsgränser och felhantering.