Your AI Connector Docs

Kontakt-API

En kontakt er en enkelt person, du sender beskeder til — deres navn, telefonnummer, e-mail, kanal, tags, brugerdefinerede felter samt de lister og kampagner, de tilhører. Kontakt-API’et giver dig mulighed for at oprette kontakter, slå dem op, opdatere dem, tilføje tags, importere dem i bulk og fjerne dem, alt sammen uden at bruge dashboardet.

Alle stier på denne side er relative til basis-URL’en:

https://api.youraiconnector.com/v1

Så /contacts betyder https://api.youraiconnector.com/v1/contacts.

Er du ny til API’et? Læs API-adgang først — den dækker, hvordan du genererer din API-nøgle, de tre måder at godkende på, hastighedsbegrænsninger og fejlformatet. Alt på denne side forudsætter, at du allerede har en fungerende API-nøgle.


Om kontakt-ID’er

Hver kontakt har et unikt ID. Det ID, du får tilbage, når du opretter en kontakt (i data.contactId), er det samme ID, som du bruger alle andre steder — til at hente, opdatere, tilføje tags, sende en besked eller slette den pågældende kontakt. Gem det én gang og genbrug det.

Du behøver ikke at oprette en kontakt for at få dens ID. Du kan også slå et ID op via telefonnummer eller e-mail (se Hent en kontakt), eller gennemse alle dine kontakter (se List kontakter). Hver af disse returnerer det samme ID.


Opret en kontakt

POST /contacts

Tilføjer en ny kontakt til din konto. Et telefonnummer med landekode er påkrævet — en e-mail alene er ikke nok. Alt andet er valgfrit.

Du kan valgfrit tilføje den nye kontakt direkte til en eller flere lister med listId (en enkelt liste) eller listIds (et array). Hvis begge sendes, vinder listIds.

Ethvert felt, du sender, som ikke er et af standardfelterne til oprettelse, der er angivet i tabellen Opret en kontakt nedenfor (phoneNumber, firstName, lastName, email, channel, is_bot_active, is_private, lead_profile, listId, listIds, custom_fields), gemmes automatisk som et brugerdefineret felt — så en flad payload fra et værktøj som Make eller Zapier fungerer uden indlejring. Du kan også sende et eksplicit custom_fields-objekt.

Felt Påkrævet Beskrivelse
phoneNumber Ja Kontaktens telefonnummer med landekode (f.eks. +15551234567).
firstName Nej Fornavn.
lastName Nej Efternavn.
email Nej E-mailadresse.
channel Nej Beskedkanal. En af whatsapp, sms, whatsapp_web. Standard er whatsapp.
is_bot_active Nej Hvorvidt AI-assistenten svarer denne kontakt. Standard er true.
is_private Nej Markér kontakten som privat. Når true, er AI-assistenten slået fra for dem. Standard er false.
lead_profile Nej Noter i fritekst om emnet.
listId Nej Et enkelt liste-ID, som kontakten skal tilføjes til.
listIds Nej Et array af liste-ID’er, som kontakten skal tilføjes til (har forrang over listId).
custom_fields Nej Et objekt med dine egne nøgle/værdi-felter. Du kan også sende disse som top-level nøgler. Felter med en type (dato, tal, dropdown, afkrydsningsfelt) valideres — se Brugerdefinerede felttyper.

Almindelige alternative navne accepteres, når det standardmæssige mangler: phone eller phone_number for nummeret, first_name og last_name for navnet, samt full_name eller name, som er opdelt i fornavn og efternavn. En Missing required fields: phoneNumber-fejl betyder derfor, at der slet ikke er modtaget nogen telefonværdi, ikke at nøglen var stavet anderledes.

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 nye kontakts ID findes på data.contactId. De lister, den blev tilføjet til, returneres i data.listsAdded.

Duplikater oprettes ikke. Hvis en kontakt med det samme telefonnummer allerede findes på den kanal, du opretter på, opretter opkaldet ikke en ekstra kontakt. Svaret returneres med HTTP-status 200 og en error_code på 409 i brødteksten, så forgrening bør baseres på error_code frem for HTTP-status. Den eksisterende kontakts ID returneres som contactId (og data.contactId), så du kan fortsætte med den med det samme:

{ "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user.", "contactId": "abc123", "data": { "contactId": "abc123" } }

Det samme gælder for en duplikeret e-mailadresse på e-mailkanalen. Hvis din team-bruger kun kan se sine egne kontakter, og den eksisterende kontakt ikke er en af dem, udelades ID’et; slå det i stedet op med Hent en kontakt via telefon eller e-mail.

Tilsvarende WhatsApp-stavemåder tæller som det samme nummer. Nogle lande har to gyldige stavemåder for den samme mobiltelefonlinje, og WhatsApp kan rapportere begge: Mexico (+52… og den ældre +521…), Brasilien (med eller uden det niende ciffer) og Argentina (med eller uden 9 efter +54). Dubletkontrollen ved oprettelse og GET /contacts?phoneNumber= matcher på tværs af begge stavemåder, så du får den eksisterende kontakt tilbage, uanset hvilken form du sender. Det phone_number, der er gemt på kontakten, bliver aldrig overskrevet.


Hent en kontakt via telefon eller e-mail

GET /contacts?phoneNumber=... eller GET /contacts?email=...

Slår en enkelt kontakt op og returnerer det fulde, berigede kontaktobjekt — inklusive dens lister, tags og kampagner opløst til { id, name }-par, plus den sidst udvekslede besked.

Angiv enten phoneNumber (i internationalt format) eller email. Hvis du ikke angiver nogen af dem, skifter dette samme slutpunkt i stedet til List kontakter-tilstand.

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"
    },
    "adAttribution": {
      "visit_at": "2026-06-09T10:14:02.000Z",
      "matched_at": "2026-06-09T10:14:20.000Z",
      "match_method": "reference",
      "reference": "4827",
      "fbc": "fb.1.1749463000000.IwAR...",
      "fbp": "fb.1.1749000000000.123456789",
      "fbclid": "IwAR...",
      "gclid": null,
      "gbraid": null,
      "wbraid": null,
      "utm_source": "facebook",
      "utm_medium": "paid",
      "utm_campaign": "spring-promo",
      "utm_content": null,
      "utm_term": null,
      "landing_url": "https://yoursite.com/quiz?utm_source=facebook&utm_campaign=spring-promo",
      "referrer": "https://l.facebook.com/",
      "client_ip": "203.0.113.7",
      "user_agent": "Mozilla/5.0 (iPhone; ...)",
      "site_key": "YOUR_SITE_KEY",
      "visit_id": "visit_abc123"
    }
  }
}

adAttribution er klikket på en annonce, der førte til din hjemmeside, matchet til denne kontakt af scriptet til annonceklik, eller null, når der ikke er nogen. Felterne er forklaret i Annonceklik-attribuering for WhatsApp.

Kontakt-ID’et returneres både på øverste niveau (contactId) og inde i objektet (contact.id). Hvis intet matcher, får du en 404 med { "success": false, "message": "Contact not found" }.

avatarUrl er kontaktens profilbillede, hentet fra WhatsApp eller Meta, når de sender dig en besked. Det er skrivebeskyttet: Du kan ikke indstille det, og det er null for kontakter, der ikke har et billede, eller som kontakter dig via en kanal, der ikke deler et. Betragt linket som midlertidigt frem for at gemme det, da nogle af disse billedlinks udløber og opdateres automatisk. (I liste-slutpunktet nedenfor kaldes den samme værdi avatar_url.)

Telefonnumre i URL’er. Et +-tegn i en forespørgselsstreng skal være URL-kodet som %2B, ellers læses det som et mellemrum. Eksemplerne ovenfor gør dette for dig.


Kontakter, hvis nummer er skjult

En WhatsApp Web-kontakt kan ankomme uden et telefonnummer, når WhatsApp tilbageholder det fra den tilknyttede enhed (se Kontakter, hvis nummer er skjult). Hver kontakt, du læser, indeholder to ekstra felter til dette: number_hidden (numberHidden på den enkelte kontaktform) og whatsapp_lid (whatsappLid).

  • For en kontakt med skjult nummer er phone_number lig med null, number_hidden er lig med true, og whatsapp_lid indeholder WhatsApps interne id i formen 153055538446346@lid. Det er ikke et nummer, der kan ringes op. Match kontakten på det id fra dit eget system, og send det som phoneNumber til dette opslag for at finde kontakten igen.
  • For alle andre kontakter er number_hidden lig med false, og whatsapp_lid er det id, som WhatsApp rapporterede for kontakten, eller null.

Udgående webhooks og automatiserings-payloads, der inkluderer en kontakt, indeholder de samme tre felter, og CSV-eksporten af kontakter har kolonnerne Number Hidden og WhatsApp LID ved siden af Phone Number. Når WhatsApp deler det rigtige nummer, opdateres kontakten automatisk, og phone_number udfyldes.

Hent en kontakt via ID

GET /contacts/{contactId}

Når du allerede har en kontakts ID, kan du hente den direkte. Svarets form er identisk med opslaget ovenfor.

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"])

Et kontakt-ID, der ikke findes på din konto, returnerer en 404.


Hent kontaktstatistik

GET /contacts/{contactId}/stats

Returnerer samlet beskedstatistik for én kontakt: totaler, AI- kontra menneskelige svar, brugte kreditter og tidsstempler for første/sidste besked.

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 er den samme AI-beskedtæller, som “nulstil”-knappen i appen for en kontakt nulstiller. creditsUsed er den løbende kredit-total for denne kontakt, ikke kun tallene for dette svar. Et kontakt-ID, der ikke findes på din konto, returnerer en 404.


Hent kontaktomkostninger

GET /contacts/{contactId}/cost

Returnerer de kreditter, en kontakt har brugt, opdelt pr. samtale (chatsession), pr. handlingstype og de gennemsnitlige omkostninger for en samtale, som AI’en håndterede alene, kontra en, som dit team trådte ind i. Brug det til at vise en klient, hvad en samtale koster.

cURL

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost?apiKey=YOUR_API_KEY"

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.total_credits, data.by_session.length);

Python

import requests

res = requests.get(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/cost",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["total_credits"], data["summary"]["contained"]["avg_credits"])

Svar

{
  "success": true,
  "contact_id": "contact_abc123",
  "total_credits": 23,
  "refunded_credits": 0,
  "unattributed_credits": 0,
  "by_session": [
    {
      "session_id": "hpWKxuTSXIKlylze5Ulx",
      "start": "2026-09-21T00:00:00.000Z",
      "end": "2026-09-24T17:41:52.052Z",
      "status": "ChatSessionClosed",
      "tag": null,
      "credits": 7,
      "actions": 7,
      "outcome": "handed_off"
    },
    {
      "session_id": "5kKnkI3DD4THIh2YVjey",
      "start": "2026-09-09T00:00:00.000Z",
      "end": "2026-09-11T22:42:34.056Z",
      "status": "ChatSessionClosed",
      "tag": null,
      "credits": 13,
      "actions": 14,
      "outcome": "contained"
    }
  ],
  "by_type": [
    { "type": "AI Chat Conclude Evaluation", "credits": 8, "actions": 8 },
    { "type": "AI Tool Use", "credits": 4, "actions": 4 },
    { "type": "AI Message", "credits": 2, "actions": 2 }
  ],
  "summary": {
    "contained": { "sessions": 1, "credits": 13, "avg_credits": 13 },
    "handed_off": { "sessions": 1, "credits": 7, "avg_credits": 7 },
    "no_ai": { "sessions": 0, "credits": 0, "avg_credits": 0 }
  },
  "sessions_truncated": false
}

Feltnoter:

  • total_credits tæller hver debitering på kontakten (AI-svar, værktøjsopkald, tags, opfølgninger, resuméer, baggrundsevalueringsskridt, skabelon- og leveringsgebyrer) med refusioner på kontakten fratrukket. Kreditbevillinger, påfyldninger og fornyelser tilhører aldrig en kontakt. Testkørsler i Playground er udeladt.
  • En debitering lander i den samtale, hvis vindue den falder indenfor. Et vindue løber fra samtalens start, indtil den lukkes, eller den næste samtale starter, så ingen debitering tælles to gange. Debiteringer uden for ethvert vindue er i unattributed_credits (og i totalen).
  • outcome: contained betyder, at AI’en svarede, og ingen fra dit team behøvede at træde til; handed_off betyder, at nogen sendte en besked, efter AI’en havde svaret, eller AI’en alarmerede et menneske; no_ai betyder, at AI’en aldrig svarede i den samtale.
  • Op til 200 samtaler er listet, de nyeste først; sessions_truncated er true, når der er flere.
  • For en bureauklient, send sub_account_id; tallene er i den klients egne kreditter.
  • creditsUsed på Hent kontaktstatistik er en løbende tæller, der holdes på kontakten. Dette endpoint genopbygger tallet fra kreditbogen, så de to kan afvige en lille smule, primært på ældre kontakter.
  • Teammedlemmer skal have faktureringstilladelse. En kontakt, der ikke er på din konto, returnerer 404; 503 betyder, at tallene ikke kan beregnes lige nu, prøv igen kort efter.

List kontakter

GET /contacts

Kald GET /contacts med hverken phoneNumber eller email for at gennemse alle dine kontakter, med de nyeste først. Hver side returnerer kompakte kontaktoversigter (lister, tags og kampagner returneres som ID-arrays i stedet for fulde objekter) og en next_cursor.

Forespørgselsparameter Beskrivelse
limit Sidestørrelse. Standard er 50, maksimum 100.
cursor next_cursor-værdien fra den forrige side. Udelad den på den første side.
listId Valgfri. Returner kun kontakter, der tilhører denne liste.

For at gennemgå hver side: foretag det første kald uden en markør (cursor), og fortsæt derefter med at sende den returnerede next_cursor tilbage som cursor. Stop når next_cursor er null — det betyder, at der ikke er flere resultater.

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",
      "number_hidden": false,
      "whatsapp_lid": null,
      "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",
      "ad_attribution": null
    }
  ],
  "next_cursor": "contact_abc123"
}

Hver kontakt bærer ad_attribution: klikket på en annonce, der førte til din hjemmeside, matchet til kontakten, med de samme felter som adAttribution i Hent en kontakt via ID, eller null, når der ikke er nogen.

Bemærk: Filtrering efter en listId, der ikke findes på din konto, returnerer en 404. En ugyldig cursor returnerer en 400.


Tæl kontakter

GET /contacts/count

Returnerer hvor mange kontakter der matcher et filter, plus en opdeling pr. kanal, uden at skulle gennemse dem side for side. Dette er det rette kald til ethvert “hvor mange”-spørgsmål — en dashboard-flise, en automatisering eller når du spørger Champ. Alle filtre er valgfrie, og kombination af flere indsnævrer optællingen (en kontakt skal matche hver enkelt, du sender).

Forespørgselsparameter Beskrivelse
agentId Kun kontakter tildelt denne AI-agent. Send none for kontakter uden tildelt agent (disse besvares af kanalens standardagent).
channel Kun kontakter på denne kanal, f.eks. whatsapp, messenger, instagram, sms, email, chat_widget.
tag Kun kontakter med dette tag, efter tag-navn (store/små bogstaver er underordnet). Et tag-navn, du ikke har, returnerer en 404.
listId Kun kontakter på denne liste.
botActive true eller false — kun kontakter, hvis AI-assistent er tændt eller slukket.
status Kun kontakter med denne status, f.eks. Lead.
rules Et URL-kodet JSON-regelobjekt, der bruger samme form som en smart liste (se The smart_rules shape længere nede). Kan ikke kombineres med de andre filtre.

Send slet intet filter, og du får det samlede antal kontakter på din 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 opdeler det samme totalantal pr. kanal; kontakter, der ikke er på nogen kanal, tælles under none. filters sender de anvendte filtre retur, så du kan kontrollere, at kaldet gjorde, hvad du forventede.

Bemærk: Hvis du sender rules sammen med et andet filter, eller en rules-værdi, der ikke er gyldig JSON, returneres en 400. Et tag-navn eller liste-ID, der ikke findes på din konto, returnerer en 404.


Opdater en kontakt

PUT /contacts/{contactId}

Opdaterer en eksisterende kontakt. Kun de felter, du inkluderer, ændres — udelad alt, du ikke ønsker at røre ved. Du skal sende mindst ét felt, ellers får du en 400 (“Ingen felter at opdatere”).

Felt Beskrivelse
firstName Fornavn.
lastName Efternavn.
email E-mailadresse.
is_bot_active Hvorvidt AI-assistenten svarer denne kontakt.
is_private Markér som privat. Hvis denne sættes til true, slås AI-assistenten også fra.
do_not_disturb Sæt automatisk outreach til denne kontakt på pause. Stopper også AI’en fra at svare.
follow_ups_disabled Stop alle automatiske opfølgninger for denne kontakt (hurtig, cyklus og kold-emne), mens AI’en fortsætter med at svare på beskeder, de sender. Nyttigt, når nogen har købt. Forbliver slået fra, indtil du sætter den tilbage til false.
lead_profile Noter om emnet i fritekst.
custom_fields Et objekt med brugerdefinerede felter. Flettes pr. nøgle — kun de nøgler, du sender, skrives; resten af de eksisterende brugerdefinerede felter bevares. Du kan også sende nøgler til brugerdefinerede felter på øverste niveau. Typede felter valideres, og en ugyldig værdi afviser anmodningen med field_errors — se Brugerdefinerede felttyper.

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"
}

Brugerdefinerede felter flettes, ikke erstattes. Afsendelse af { "custom_fields": { "tier": "gold" } } indstiller kun tier — alle andre brugerdefinerede felter på kontakten forbliver præcis, som de var. For at fjerne et brugerdefineret felt helt på tværs af alle kontakter, skal du bruge Slet et brugerdefineret felt.


Tilføj eller fjern tags

POST /contacts/{contactId}/tags

Tilføjer og/eller fjerner tags på en enkelt kontakt i ét kald. Send tag-ID’er i addTagIds og removeTagIds. Mindst ét af de to skal være ikke-tomt.

Tags skal allerede eksistere på din konto — opret dem først via tags-endpointet. Hvis kontakten eller et refereret tag ikke findes, får du en 404.

Felt Beskrivelse
addTagIds Array af tag-id’er, der skal tilføjes til kontakten.
removeTagIds Array af tag-id’er, der skal fjernes fra 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
}

Administrer dit tag-bibliotek

Disse slutpunkter administrerer selve tagget — omdøbning eller sletning af det på din konto — i modsætning til at tilføje eller fjerne et tag på en kontakt (se Tilføj eller fjern tags ovenfor). Hvert tag på din konto har et ID (tagId): det, der vises i dit dashboards tag-manager, og det, der returneres som tag_id på øverste niveau af svaret, når du opretter et tag med POST /tags og en JSON-brødtekst på { "name": "..." } (ingen phoneNumber, email eller contactId).

Opdater et tag

PUT /tags/{tagId}

Send kun de felter, du ændrer.

Felt Beskrivelse
name Taggets navn.
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" }

Et tagId, der ikke findes på din konto, returnerer en 404.

Slet et tag

DELETE /tags/{tagId}

Sletter ét tag efter ID. Dette kan ikke fortrydes — kontakter, der bærer tagget, mister det blot. Sletning af et tag, der allerede er væk (eller aldrig har eksisteret), returnerer 200 med deleted: 0 i stedet for en 404, da der ikke er noget at tælle op.

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"

Svar

{ "success": true, "deleted": 1 }

Slet flere tags på én gang

DELETE /tags

Felt Beskrivelse
tagIds Array af tag-id’er, der skal slettes (maks. 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’er, der ikke findes, eller som tilhører en anden konto, springes over uden fejlmeddelelse og tælles ikke med i deleted.


Masseindstil et flag

POST /contacts/bulk-flag

Indstiller ét boolesk flag på mange kontakter på én gang. Op til 500 kontakt-id’er pr. anmodning. Id’er, der ikke findes på din konto, springes over og tælles i skipped.

Felt Beskrivelse
contactIds Array af kontakt-id’er, der skal opdateres (maks. 500).
field Hvilket flag der skal indstilles. Et af bot_active (AI-assistent til/fra), dnd (pause automatiseret kontakt), spam, private.
value Den booleske værdi, flaget skal indstilles til.

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
}

Masseimport af kontakter

POST /contacts/import

Opretter op til 500 kontakter i ét kald fra et JSON-array. Hver post kræver et phone_number i internationalt format; alt andet er valgfrit. Poster med ugyldige telefonnumre eller ikke-understøttede kanaler springes over (oprettes ikke), og hver overspringet post rapporteres med sit indeks og årsag — så du kun behøver at rette fejlene og prøve igen.

Telefonnumre, der allerede findes på din konto, springes som standard over som duplicate — men når du sender en listId, tilføjes den kontakt, du allerede har, stadig til listen og tælles under added_to_list, så en genimport udfylder listen uden at ændre noget på kontakten. Send updateExisting: true for at opdatere disse kontakter i stedet: felterne i posten overskriver kontaktens (first_name, last_name, email, lead_profile og custom_fields flettes nøgle for nøgle), tags tilføjes, og kontakten tilføjes til listId. Kanal, telefonnummer og bot-flag ændres aldrig på en eksisterende kontakt.

Du kan valgfrit tilføje hver importeret (eller opdateret) kontakt til en liste med listId, angive en defaultChannel for poster, der ikke angiver en, og tagge poster med tags (tagnavne — manglende tags oprettes, eksisterende matches uafhængigt af store/små bogstaver).

Top-niveau felter

Felt Påkrævet Beskrivelse
contacts Ja Array af kontaktposter (maks. 500).
listId Nej Liste, som alle kontakter i denne anmodning skal tilføjes til — både oprettede, opdaterede og dem, der blev sprunget over som dubletter. Skal være en liste på din konto.
defaultChannel Nej Kanal anvendt på poster, der udelader channel. En af whatsapp, sms, whatsapp_web. Standard er whatsapp.
updateExisting Nej true for at opdatere kontakter, hvis telefonnummer allerede findes, i stedet for at springe dem over som duplicate. Standard er false.

Felter pr. post

Felt Påkrævet Beskrivelse
phone_number Ja Telefonnummer i internationalt format (et indledende + tilføjes, hvis det mangler).
first_name Nej Fornavn.
last_name Nej Efternavn.
email Nej E-mailadresse.
channel Nej En af whatsapp, sms, whatsapp_web. Falder tilbage på defaultChannel.
is_bot_active Nej Hvorvidt AI-assistenten svarer. Standard er true.
is_private Nej Marker som privat. Standard er false.
lead_profile Nej Fritekst-notater om emnet.
custom_fields Nej Objekt med brugerdefinerede feltnøgler og værdier.
tags Nej Array af tagnavne (en enkelt "a; b" streng virker også). Tags, der ikke findes, oprettes; eksisterende matches uden hensyntagen til store/små bogstaver. Maks. 25 pr. 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": [],
  "added_to_list": 0,
  "added_to_list_contact_ids": [],
  "skipped": []
}

Hvis nogle poster ikke kan oprettes, vises de i skipped med årsagen (her uden updateExisting, så det eksisterende nummer springes over):

{
  "success": true,
  "imported": 1,
  "contact_ids": ["contact_abc123"],
  "updated": 0,
  "updated_contact_ids": [],
  "added_to_list": 1,
  "added_to_list_contact_ids": ["contact_def456"],
  "skipped": [
    { "index": 1, "phone_number": "+12025551235", "reason": "duplicate" }
  ]
}

Den overspringne række blev stadig tilføjet listId, hvilket er det, added_to_list tæller — intet andet på den kontakt blev berørt. Med updateExisting: true rapporterer den samme anmodning den eksisterende kontakt under updated / updated_contact_ids i stedet.

Mulige årsager til spring over: invalid_record, missing_phone_number, invalid_phone_number, invalid_channel, duplicate_in_request, duplicate, contact_limit_reached, create_failed.

Planbegrænsninger. Hvis din plans kontaktgrænse ikke tillader så mange nye kontakter, afvises hele anmodningen på forhånd med en 403. Hvis grænsen nås undervejs, returneres de resterende poster som sprunget over med årsagen contact_limit_reached.


Importér kontakter fra en CSV-fil

Ved importer, der er større end hvad bulk import understøtter (op til cirka 50.000 rækker), skal du køe et asynkront importjob mod en CSV-fil, der allerede ligger i din kontos lager, og derefter polle det, indtil det er fuldført.

Start importen

POST /contacts/import-csv

Felt Påkrævet Beskrivelse
csvStoragePath Ja Lagersti til CSV-filen under users/{your account id}/imports/, der slutter på .csv.
listName Ja Opretter (eller genbruger) en liste med dette navn og tilføjer alle importerede kontakter til den.
existingListRefs Nej Array af eksisterende liste-id’er, som alle importerede kontakter også skal tilføjes til.
defaultChannel Nej Kanal anvendt på rækker, der ikke angiver en.
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 er sat i kø, ikke færdig endnu)

{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "queued"
}

Få filen ind i lageret. Dette endepunkt starter og sporer importjobbet; det accepterer ikke selv en upload. CSV-filen skal allerede findes på csvStoragePath, før du kalder det — dashboardets egen CSV-importør gør dette som sit første skridt.

Polling af 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 bevæger sig gennem queued → processing → completed eller failed med årsagen i error_message. Et jobId, der ikke findes på din konto, returnerer en 404.


Eksportér kontakter

Starter en asynkron CSV-eksport af dine kontakter og returnerer et job, som du kan polle for færdiggørelse.

Start eksporten

POST /contacts/export

Felt Påkrævet Beskrivelse
listId Nej Eksportér kun kontakter, der tilhører denne liste.
contactIds Nej Eksportér kun disse specifikke kontakt-id’er.

Hvis begge udelades, eksporteres alle kontakter på din 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 — eksporten er sat i kø)

{
  "success": true,
  "job_id": "export_abc123",
  "status": "queued"
}

Forespørg eksportjobbet

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 er "completed", modtager du export_id og contact_count. Download af den genererede CSV-fil sker fra dit kontrolpanels Eksport-side.


Send en besked til en kontakt

POST /contacts/{contactId}/send-message

Sender en besked til en eksisterende kontakt på den kanal, de allerede befinder sig på. Beskeden sættes i kø og leveres i baggrunden — svaret bekræfter, at den blev accepteret, ikke at den er blevet leveret endnu.

Felt Påkrævet Beskrivelse
body Ja Teksten i beskeden, der skal sendes.
mediaUrl Nej URL til en mediefil, der skal vedhæftes.
mediaContentType Nej MIME-type for det vedhæftede medie (f.eks. 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 ikke sende lige nu? Hvis kontakten har aktiveret forstyr-ikke eller privat tilstand, eller ikke er på en kanal, der kan modtage udgående beskeder, afvises anmodningen med en 422 og en forklarende error.

For afsendelse via telefonnummer, Instagram-id eller anden kanalidentitet i stedet for et kontakt-id — og for mere om beskeder generelt — se Messages API.


Send en AI-opfølgning til en kontaktperson

POST /contacts/{contactId}/ai-follow-up

Får en AI-agent til at skrive én besked med sin egen stemme, baseret på samtalen indtil videre og en instruktion, du giver, og sender den via kontaktpersonens kanal. Det er det samme som automatiseringstrinnet Send AI-opfølgning, og det koster det samme antal kreditter som en AI-opfølgning.

Felt Påkrævet Beskrivelse
instruction Ja Hvad beskeden skal gøre, med almindelige ord, op til 2.000 tegn. For eksempel “Mind dem om, at deres reserverede link udløber i aften, og spørg, om de vil låse det fast”.
agentId Nej Den agent, der skriver beskeden. Lad feltet stå tomt for at bruge den agent, der allerede håndterer kontaktpersonen.
mustContain Nej En liste med op til 5 sætninger eller links (hver på op til 500 tegn), som beskeden skal indeholde ordret. Hvis AI’en udelader en af dem, sendes intet, og skipReason er text_check_failed.
respectMessagingWindow Nej Standard true. På WhatsApp Business API, Instagram og Messenger springes trinnet over, hvis kontaktpersonens sidste besked er mere end 24 timer gammel.
skipWhenAiPaused Nej Standard true. Spring over, hvis AI’en er slået fra for denne kontaktperson.

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/ai-follow-up" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instruction": "Remind them their reserved link expires tonight and ask if they want to lock it in",
    "mustContain": ["https://example.com/r/abc123"]
  }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/ai-follow-up", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    instruction: "Remind them their reserved link expires tonight and ask if they want to lock it in",
    mustContain: ["https://example.com/r/abc123"],
  }),
});
const data = await res.json();
if (!data.sent) console.log("Skipped:", data.skipReason);

Svar, når beskeden blev sendt:

{
  "sent": true,
  "messageId": "ai-follow-up-aB3dE5fG7hI9jK1l",
  "text": "Hi Ada, quick reminder: your reserved spot is held until 20:00 tonight. Want to lock it in? https://example.com/r/abc123",
  "agentId": "agent_abc123"
}

Svar, når den blev sprunget over:

{
  "sent": false,
  "skipReason": "window_closed"
}

Begge returnerer status 200. skipReason er en af no_agent (ingen agent håndterer kontakten, og ingen blev angivet), dnd (forstyr ikke), ai_paused, window_closed (uden for 24-timers vinduet, eller kontakten har aldrig skrevet til dig på den kanal), no_credits, text_check_failed (et mustContain element manglede), no_text (AI’en skrev intet brugbart) eller linkedin_gap (et LinkedIn-lead modtog en automatisk besked for mindre end 24 timer siden; svaret indeholder derefter også nextAllowedAt, tidspunktet for hvornår den næste må sendes). Et spring over er et normalt svar, ikke en fejl, så tjek sent før du antager, at beskeden blev sendt. Et overspringet kald bruger ingen kreditter.

Et body-felt, der mangler instruction eller har et felt af den forkerte type, får en 400. En kontaktperson eller agent, der ikke findes i din konto, får en 404. Fejl returneres som { "success": false, "error": "..." }. Et teammedlems nøgle skal have redigeringsadgang til kontaktpersoner.


Tildel en AI-agent til en kontakt

POST /contacts/{contactId}/assign-agent

Flytter en eksisterende samtale til en anden AI-agent, fra og med den næste besked. Det er det samme som Tildel AI-agent i en chats menu, og det samme trin, som handlingen Tildel AI-agent bruger i Automatiseringer.

Felt Påkrævet Beskrivelse
agentId Ja ID’et på den AI-agent, der skal overtage, eller null for at rydde tildelingen, så samtalen går tilbage til din team-indbakke.
triggerAIResponse Nej true får den nyligt tildelte agent til at svare på kontaktens seneste ubesvarede beskeder med det samme. Standard er false. Når kontakten allerede var tilknyttet denne agent, og dennes sidste besked allerede er besvaret, startes intet svar: svaret indeholder aiResponseTriggered: false og en aiTriggerError, der forklarer hvorfor.

Vær forsigtig med triggerAIResponse: true — den sender en besked til kontakten med det samme, så brug den kun, når du ønsker, at de skal kontaktes nu. På Messenger og Instagram fejler beskeden, hvis kontakten sidst skrev til dig for mere end 24 timer siden.

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 skal tilhøre den samme konto som kontakten; ellers afvises anmodningen med en 404 eller 403. Find agent-ID’er på siden AI-agenter (hver agents URL slutter med dens ID).


Tildel en AI-agent til mange kontakter

POST /contacts/bulk-assign-agent

Flytter mange samtaler til en anden AI-agent i ét kald — eller rydder tildelingen for dem alle med null. Det er udelukkende en routing-ændring: ingen besked sendes, og agenten svarer ikke nogen. Hver kontakt får blot den nye agent, næste gang de skriver. (Det er derfor, der ikke er nogen triggerAIResponse her.)

Felt Påkrævet Beskrivelse
agentId Ja Den AI-agent, der skal overtage, eller null for at rydde tildelingen.
contactIds Én af de tre Op til 500 kontakt-ID’er, der skal flyttes.
filter Én af de tre Vælg kontakterne på serveren i stedet for at angive dem, nyeste først. Bruger de samme nøgler som tælle-endepunktets filtre: agentId (eller none), channel, tag, listId, botActive, status.
rules Én af de tre Et smart-liste-regelobjekt — se The smart_rules shape.
limit Nej Hvor mange kontakter der skal flyttes i dette kald, når du vælger med filter eller rules. 1 til 500, standard er 500.

Send præcis én af 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 er hvor mange kontakter udvalget fandt i alt, updated hvor mange der blev flyttet af dette kald, skipped hvor mange af de ID’er, du sendte, der ikke blev fundet på din konto, og remaining hvor mange der stadig matcher nu, hvor kaldet er færdigt.

Flytning af alle. Da et kald flytter maksimalt 500 kontakter, kræver en stor gruppe nogle få kald. Brug et filter, der holder op med at matche en kontakt, når den er flyttet — for eksempel filter: { "agentId": "agent_abc123" } mens der tildeles til agent_xyz789 — og gentag det præcis samme kald, indtil remaining kommer tilbage som 0. Når du i stedet sender contactIds, er remaining altid 0.


Tildel en kontakt til en afdeling

POST /contacts/{contactId}/department

“Tildel dette lead til Salg” — placerer en kontakt under en navngiven afdeling og giver den som standard til den person i afdelingen, der i øjeblikket har færrest kontakter. Dette er adskilt fra tildeling af en AI-agent: en afdeling besvarer “hvilket team ejer dette,” en agent besvarer “hvilken AI besvarer dette,” og indstilling af den ene sletter aldrig den anden.

Felt Påkrævet Beskrivelse
department_id Ja Afdelingen, som kontakten skal placeres under. Send null for at rydde den.
hand_to_member Nej Giv også kontakten til den person i afdelingen, der har mindst at lave. Standard er true. Omfordeler aldrig en kontakt, som nogen allerede ejer.

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 er null, når kontakten allerede var ejet af nogen, eller du sendte hand_to_member: false.


“Fortsæt på WhatsApp” (eller SMS) finder eller opretter denne persons kontakt på en anden telefonbaseret kanal og linker de to sammen, så resten af appen genkender dem som den samme person.

POST /contacts/{contactId}/link-channel

Felt Påkrævet Beskrivelse
channel Ja Kanalen, der skal linkes til. En af whatsapp, whatsapp_web, sms.
phoneNumber Nej Telefonnummer, der skal bruges på den nye kanal. Som standard bruges kildekontaktens 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 fortæller dig, om en ny kontakt blev oprettet til målkanalen, eller om en eksisterende blev fundet og linket. Det er sikkert at kalde dette en anden gang — det returnerer den samme contact_id med created: false i stedet for at oprette en dublet.

En 422 betyder, at kontoen ikke kan udføre dette link lige nu: kontakten er allerede på den kanalfamilie, den har intet telefonnummer at bruge, eller der er ingen forbundet afsender til målkanalen. En 409 betyder, at de to kontakter allerede er linket til to forskellige personer — fjern linket for den ene først.

Vis en kontakts linkede samtaler

GET /contacts/{contactId}/linked

Returnerer de andre samtaler, der er den samme person som denne kontakt. En ikke-linket kontakt returnerer et tomt array, ikke en 404 — “denne person har ingen andre kanaler” er en normal tilstand.

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"
      }
    }
  ]
}

DELETE /contacts/{contactId}/link

Fjerner denne kontakt fra sin person, ensidigt — alle andre kontakter, der stadig er linket til den person, beholder deres link, så at fjerne linket for én ud af tre opløser ikke 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 }

Hent en kontakts profilbillede

POST /contacts/{contactId}/profile-pic

Henter (og cacher) kontaktens WhatsApp- eller Meta-profilbillede efter behov — det samme billede, der returneres som avatarUrl i Hent en kontakt, opdateret.

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 betyder, at URL’en kom fra et nyligt opslag i stedet for et frisk udbyderopslag — billeder caches i 7 dage, og en kontakt, som udbyderen rapporterer ikke har et tilgængeligt billede, caches som utilgængelig i 24 timer. Når der ikke er noget billede at hente, udelades avatar_url, og message forklarer hvorfor.


Auto-tag kontakter med AI

Kører din kontos tag-regler over en eller flere kontakters fulde samtaleliste og tilføjer (eller fjerner) tags præcis som den realtids-tagging, der kører under en live chat — samme regler, samme kreditomkostning pr. tag.

Start en kørsel

POST /contacts/auto-tag

Felt Påkrævet Beskrivelse
scope Ja "contacts" for at tagge specifikke kontakter, eller "agent" for at tagge alle samtaler, der i øjeblikket håndteres af én AI-agent.
contact_ids Påkrævet når scope er "contacts" Array af kontakt-ID’er, 1 til 500.
agent_id Påkrævet når scope er "agent" Den AI-agent, hvis samtaler der skal tagges. Når scope er "contacts", er dette valgfrit og indsnævrer blot, hvilke af agentens tag-regler der køres.
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 enkelt kontakt køres inline og returnerer resultatet med det samme:

{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }

To eller flere kontakter (eller scope: "agent") køres som et baggrundsjob og returnerer 202 med det samme:

{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }

Forespørg en kørsel

GET /contacts/auto-tag/run

Returnerer kontoens nuværende (eller seneste) kørsel, så du kan forespørge om status uden selv at skulle spore 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 er null, når kontoen aldrig har startet en. status flytter sig fra "running" til "completed" eller "failed".

Kun én bulk-kørsel kan være i gang pr. konto ad gangen — hvis du starter en anden, mens en anden kører, returneres 409 med error_code: "auto_tag_run_in_progress". Hvis du løber tør for kreditter under en kørsel for en enkelt kontakt, returneres 402 med error_code: "insufficient_credits"; en bulk-kørsel stopper i stedet sig selv tidligt og rapporterer, hvor langt den nåede i run.


Slet en kontakt

DELETE /contacts/{contactId}

Sletter permanent én kontakt via ID, sammen med dens beskedhistorik. Dette kan ikke fortrydes. For at slette flere kontakter i et enkelt kald, brug Slet kontakter herunder.

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
}

Et kontakt-id, der ikke findes på din konto, eller som tilhører en anden konto, returnerer en 404.


Slet kontakter

DELETE /contacts

Sletter permanent en eller flere kontakter via id i et enkelt kald (op til 500 id’er). Id’er, der ikke findes på din konto, springes over og tælles i skipped. Dette kan ikke fortrydes.

Felt Beskrivelse
contactIds Array af kontakt-id’er, der skal slettes (maks. 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
}

List tilpassede felter

GET /users/me/custom-fields — returnerer de tilpassede feltnøgler, der er registreret på din konto (dem, der vises som kolonner og i kontaktformularen), så en integration kan tilbyde dem som et valgfelt i stedet for at gætte.

curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/users/me/custom-fields?apiKey=YOUR_API_KEY"

Svar (200)

{ "success": true, "custom_fields": ["tier", "company", "birthday"] }

Angiv listen med PUT /users/me/custom-fields og den samme array-form.


Slet et brugerdefineret felt

DELETE /contacts/custom-fields/{fieldKey}

Fjerner én brugerdefineret feltnøgle fra alle kontakter på din konto. Brug dette til at rydde op efter omdøbning eller fjernelse af et brugerdefineret felt. Nøglen må kun indeholde bogstaver, tal, understregninger og bindestreger. Returnerer hvor mange kontakter der blev opdateret. Dette kan ikke fortrydes.

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
}

Bemærk: En feltnøgle med ikke-understøttede tegn returnerer en 400.


Brugerdefinerede felttyper

Hvert brugerdefineret felt på en konto har en type: text (standard), number, date, select (en dropdown med faste valgmuligheder) eller boolean (et afkrydsningsfelt). Et typet felt valideres ved hver skrivning — oprettelse, opdatering, import, automatiseringsmotoren og AI’ens egen feltindsamling — og værdien gemmes i én kanonisk form, så filtre og automatiseringsbetingelser sammenligner ens med ens:

Type Gemt som Accepteret ved input
text Hvad end du sender Alt (uændret opførsel)
number Et JSON-tal 42, "42", "19,99"
date "YYYY-MM-DD" 2026-02-01, en ISO-dato-tid (datodelen bevares), 01/02/2026 (dag-først eller måned-først afhængigt af kontoens datoformat; en entydig værdi som 13/02/2026 vinder altid), February 1, 2026, 1 de febrero de 2026
select En af feltets valgmuligheder, stavet som valgmuligheden selv Ethvert match af en valgmulighed (uafhængigt af store/små bogstaver)
boolean true / false true/false, yes/no, 1/0, si/no, ja/nein …

Hvis du sender null eller en tom streng, ryddes et typet felt. Nøgler, der ikke er registreret på kontoen, og text-felter gemmes præcis som sendt.

Læs feltdefinitionerne

GET /users/me/custom-fields

{
  "success": true,
  "custom_fields": ["company", "birthday", "plan", "vip"],
  "definitions": [
    { "key": "company", "type": "text" },
    { "key": "birthday", "type": "date" },
    { "key": "plan", "type": "select", "options": ["Free", "Pro", "Enterprise"] },
    { "key": "vip", "type": "boolean" }
  ]
}

custom_fields er den simple liste over nøgler (uændret for ældre klienter); definitions indeholder typen pr. nøgle.

Angiv feltdefinitionerne

PUT /users/me/custom-fields

Erstatter hele listen. Hver post er enten en rå nøgle (bevarer den type, feltet allerede har, text for et nyt) eller et objekt med key, type og, for select, options (1 til 100 unikke valgmuligheder, op til 64 tegn hver). Op til 50 felter; nøgler bruger små bogstaver, tal og understregninger og starter med et bogstav eller en understregning.

curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/users/me/custom-fields?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customFields": [
      "company",
      { "key": "birthday", "type": "date" },
      { "key": "plan", "type": "select", "options": ["Free", "Pro", "Enterprise"] },
      { "key": "vip", "type": "boolean" }
    ]
  }'

Ændring af et felts type overskriver ikke værdier, der allerede er gemt på kontakter; de valideres næste gang, de skrives.

Valideringsfejl

En oprettelse eller opdatering af en kontakt, hvis brugerdefinerede feltværdier ikke passer til deres type, afvises i sin helhed med en 400:

{
  "success": false,
  "error": "Invalid custom field value(s): birthday: \"birthday\" must be a date in YYYY-MM-DD format (for example 1990-02-01).",
  "field_errors": [
    { "key": "birthday", "message": "\"birthday\" must be a date in YYYY-MM-DD format (for example 1990-02-01)." }
  ]
}

Ved en bulk-import rapporteres posten med den forkerte værdi som mislykket med den samme meddelelse, og resten af batchet gennemføres.


Lister

Lister grupperer kontakter. En liste er enten statisk (du bestemmer, hvem der er på den) eller smart (medlemskab beregnes ud fra regler og holdes automatisk opdateret — se Organisering af lister og kontakter).

Felt Beskrivelse
name Påkrævet ved oprettelse. Op til 100 tegn.
status live (standard) eller draft. Små bogstaver.
contact_ids Array af kontakt-id’er, der skal tilføjes listen. Kun statiske lister.
type static (standard) eller smart.
smart_rules Regelsættet — påkrævet når type er smart. Se nedenfor.

Opret en liste

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 liste evalueres inline i den samme anmodning, så evaluation fortæller dig præcis, hvem der endte på den. På en statisk liste er evaluation lig med null.

Opdater en liste

PUT /lists/{listId}

Send kun de felter, du ændrer. Ændring af smart_rules gen-evaluerer listen med det samme og returnerer det samme 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 skifte en liste mellem de to typer:

  • Statisk → smart: send { "type": "smart", "smart_rules": { … } }. Reglerne tager over med det samme.
  • Smart → statisk: send { "type": "static" }. Reglerne fjernes, og alle, der er på listen, bliver der.

Formen på 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 (alle betingelser skal være sande) eller any (mindst én).
  • conditions — 1 til 20 betingelser, hver med højst 100 værdier, strenge på op til 200 tegn.
field op value
tags has_any, has_all, has_none array af tag-ID’er
lists in_any, not_in_any array af liste-ID’er (kun statiske lister — en smart liste kan ikke bygges ud fra en anden smart liste)
channel is_any, is_none array af kanaler
status is_any, is_none array af kontaktstatusser
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" }
samme dato-felter before, after ISO-dato ("2026-01-01", sammenlignes som hele dage) eller fuld ISO-dato-tid ("2026-01-01T14:30:00Z", sammenlignes med det præcise tidspunkt)
samme dato-felter is_set, not_set —
has_interacted_with_ai is true / false — true matcher kontakter, som AI’en har sendt mindst én besked til (nogensinde)
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 streng til contains-formularerne
current_campaign_id, assigned_agent is_any, is_none, is_set, not_set array af ID’er til is_any / is_none-formularerne
custom_field (plus en key) eq, neq, contains, not_contains, is_set, not_set streng til værdiformularerne

not_within_last matcher også kontakter, hvor datoen aldrig er blevet sat (“mere end N siden, eller aldrig”), og tekstsammenligninger ignorerer store/små bogstaver.

AI-engagement. has_interacted_with_ai er lifetime-flaget: true for enhver kontakt, som din AI har sendt mindst én besked til, false for alle andre (inklusive kontakter, som kun dit team nogensinde har svaret). Det stemples ved AI’ens første besked til en kontakt og slettes aldrig, så at slå AI-svar fra for kontakten eller flytte dem til en anden kampagne nulstiller det ikke. For en periode — “de kontakter min AI håndterede i denne måned”, det sædvanlige faktureringsspørgsmål — skal du bruge et interval over last_ai_interaction_at i stedet:

{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }

Forveksl ikke nogen af dem med is_bot_active (AI’en har tilladelse til at svare, ikke at den har gjort det) eller has_ever_responded (kontakten skrev tilbage, til hvem som helst). De samme to stempler returneres på hver kontakt som first_ai_interaction_at / last_ai_interaction_at, og hele regelsættet fungerer også på GET /contacts?rules=, så du kan tælle matches uden at oprette en liste.

Få vist et regelsæt

POST /lists/preview

Tæller og sampler de kontakter, som et regelsæt ville matche, uden at oprette eller ændre noget. Brug det til at kontrollere reglerne, før du gemmer 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 indeholder op til 10 kontakter, sorteret efter seneste aktivitet først.

Kør en smart liste igen nu

POST /lists/{listId}/evaluate

Tvinger en øjeblikkelig genberegning (det samme som Opdater nu gør i dashboardet). Smarte lister opdateres allerede, når en kontakt ændres, og hvert 15. minut for tidsbaserede regler, så dette er kun nødvendigt, når du vil have resultatet lige nu.

Svar

{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 2, "removed": 1, "total": 4 }
}

evaluation.skipped: true betyder, at en anden evaluering af den samme liste allerede kørte, og dette kald gjorde intet.

Smarte lister afviser manuelt tilføjede medlemmer

Medlemskabs-endpoints returnerer 409 med "This is a smart list — its members are computed from its rules. Edit the rules instead.", når mållisten er smart. Det dækker POST /contacts/lists, DELETE /contacts/lists, POST /contacts/lists/batch, contact_ids på POST /lists og PUT /lists/{listId}, samt valg af en smart liste som mål for CSV-import. Ændr reglerne i stedet.

At kalde POST /lists/{listId}/evaluate på en statisk liste er også en 409 — den har ingen regler at køre.


Kontakter API-fejl

Kontakt-endpoints returnerer standardfejlkonvolutten:

{
  "success": false,
  "error": "Contact not found"
}

Nogle slutpunkter inkluderer også error_code, som normalt matcher HTTP-status — den eneste undtagelse er tilfældet med dublerede kontakter nedenfor, hvor HTTP-status er 200, og kun error_code bærer 409. Koderne, der er specifikke for kontaktslutpunkter:

Kode Hvornår det sker på et kontakt-endepunkt
400 Ugyldig anmodning — et manglende/ugyldigt felt, tom brødtekst, dårlig markør eller over 500 id’er i en batch.
402 Ikke nok kreditter til at fuldføre en AI-tagging-kørsel på én kontakt (error_code: "insufficient_credits").
404 Kontakten, listen eller tagget blev ikke fundet på din konto.
409 En kontakt med det telefonnummer findes allerede (ved oprettelse). Returneres som error_code i brødteksten med en HTTP-status på 200, så forgrening på error_code her. Returneres også, når en automatisk bulk-tagging-kørsel allerede er i gang (error_code: "auto_tag_run_in_progress"), eller når sammenkædning af en kontakt til en anden kanal ville forbinde to kontakter, der allerede er knyttet til to forskellige personer.
422 Kontakten kan ikke modtage en besked lige nu (forstyr ikke, privat eller ikke-understøttet kanal). På kanal-link-endepunktet dækker det også intet telefonnummer, en ikke-understøttet kanalparring eller ingen forbundet afsender for målkanalen.

En 403 på et kontaktslutpunkt kan også betyde et problem med kontaktgrænse eller listetilladelse frem for abonnementsadgang. De delte koder, som ethvert slutpunkt kan returnere — 401, 403 (dit abonnement inkluderer ikke API-adgang), 429 (rate limit) og 500 — er angivet med vejledning til genforsøg i Fejl & Sidetal.


Næste skridt

  • Besked-API — send beskeder via kanalidentitet og administrer samtaler.
  • API-reference — fuld liste over endpoints, inklusive tags og lister.
  • API-adgang — godkendelse, hastighedsbegrænsninger og fejlhåndtering.