Kontakte-API
Ein Kontakt ist eine einzelne Person, der Sie Nachrichten senden – mit Name, Telefonnummer, E-Mail, Kanal, Tags, benutzerdefinierten Feldern sowie den Listen und Kampagnen, denen sie angehört. Mit der Kontakte-API können Sie Kontakte erstellen, suchen, aktualisieren, mit Tags versehen, in großen Mengen importieren und entfernen, ohne das Dashboard verwenden zu müssen.
Alle Pfade auf dieser Seite sind relativ zur Basis-URL:
https://api.youraiconnector.com/v1
Das bedeutet, /contacts entspricht https://api.youraiconnector.com/v1/contacts.
Neu bei der API? Lesen Sie zuerst API-Zugriff – dort wird erklärt, wie Sie Ihren API-Schlüssel generieren, welche drei Authentifizierungsmethoden es gibt, wie Ratenbegrenzungen funktionieren und wie das Fehlerformat aussieht. Alles auf dieser Seite setzt voraus, dass Sie bereits über einen funktionierenden API-Schlüssel verfügen.
Über Kontakt-IDs
Jeder Kontakt hat eine eindeutige ID. Die ID, die Sie beim Erstellen eines Kontakts (in data.contactId) erhalten, ist dieselbe ID, die Sie überall sonst verwenden – um diesen Kontakt abzurufen, zu aktualisieren, mit Tags zu versehen, eine Nachricht zu senden oder ihn zu löschen. Speichern Sie sie einmal und verwenden Sie sie wieder.
Sie müssen einen Kontakt nicht erstellen, um seine ID zu erhalten. Sie können auch nach Telefonnummer oder E-Mail suchen (siehe Kontakt abrufen) oder alle Ihre Kontakte durchblättern (siehe Kontakte auflisten). Jede dieser Methoden gibt dieselbe ID zurück.
Kontakt erstellen
POST /contacts
Fügt Ihrem Konto einen neuen Kontakt hinzu. Eine Telefonnummer mit Ländervorwahl ist erforderlich – eine E-Mail-Adresse allein reicht nicht aus. Alles andere ist optional.
Sie können den neuen Kontakt optional direkt mit listId (eine einzelne Liste) oder listIds (ein Array) in eine oder mehrere Listen aufnehmen. Wenn beides gesendet wird, hat listIds Vorrang.
Jedes Feld, das Sie senden und das nicht eines der Standard-Erstellungsfelder in der unten stehenden Tabelle Kontakt erstellen ist (phoneNumber, firstName, lastName, email, channel, is_bot_active, is_private, lead_profile, listId, listIds, custom_fields), wird automatisch als benutzerdefiniertes Feld gespeichert — daher funktioniert eine flache Payload von einem Tool wie Make oder Zapier ohne Verschachtelung. Sie können auch ein explizites custom_fields-Objekt übergeben.
| Feld | Erforderlich | Beschreibung |
|---|---|---|
phoneNumber |
Ja | Die Telefonnummer des Kontakts mit Ländervorwahl (z. B. +15551234567). |
firstName |
Nein | Vorname. |
lastName |
Nein | Nachname. |
email |
Nein | E-Mail-Adresse. |
channel |
Nein | Messaging-Kanal. Einer der Werte whatsapp, sms, whatsapp_web. Standardwert ist whatsapp. |
is_bot_active |
Nein | Legt fest, ob der KI-Assistent auf diesen Kontakt antwortet. Standardwert ist true. |
is_private |
Nein | Markiert den Kontakt als privat. Wenn true, ist der KI-Assistent für diesen Kontakt deaktiviert. Standardwert ist false. |
lead_profile |
Nein | Freitext-Notizen über den Lead. |
listId |
Nein | Eine einzelne Listen-ID, der der Kontakt hinzugefügt werden soll. |
listIds |
Nein | Ein Array von Listen-IDs, denen der Kontakt hinzugefügt werden soll (hat Vorrang vor listId). |
custom_fields |
Nein | Ein Objekt mit Ihren eigenen Schlüssel/Wert-Feldern. Sie können diese auch als Top-Level-Schlüssel übergeben. Felder mit einem Typ (Datum, Zahl, Dropdown, Kontrollkästchen) werden validiert – siehe Benutzerdefinierte Feldtypen. |
Gängige alternative Namen werden akzeptiert, wenn der Standardname fehlt: phone oder phone_number für die Nummer, first_name und last_name für den Namen sowie full_name oder name, was in Vor- und Nachname aufgeteilt wird. Ein Missing required fields: phoneNumber-Fehler bedeutet daher, dass überhaupt kein Telefonwert angekommen ist, nicht, dass der Schlüssel anders geschrieben wurde.
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"])
Antwort
{
"success": true,
"data": {
"message": "Successfully created new contact",
"contactId": "contact_abc123",
"listsAdded": ["list123", "list456"]
}
}
Die ID des neuen Kontakts befindet sich unter data.contactId. Die Listen, denen er hinzugefügt wurde, werden in data.listsAdded zurückgegeben.
Es werden keine Duplikate erstellt. Wenn bereits ein Kontakt mit derselben Telefonnummer auf dem Kanal existiert, auf dem Sie den Kontakt erstellen, erstellt der Erstellungsaufruf keinen zweiten Kontakt. Die Antwort erfolgt mit dem HTTP-Status
200und einemerror_codevon409im Body. Verzweigen Sie daher basierend auferror_codeund nicht auf dem HTTP-Status. Die ID des bestehenden Kontakts wird alscontactId(unddata.contactId) zurückgegeben, sodass Sie direkt damit fortfahren können:{ "success": false, "error_code": 409, "error": "A contact with this phone number already exists for the current user.", "contactId": "abc123", "data": { "contactId": "abc123" } }Dasselbe gilt für eine doppelte E-Mail-Adresse auf dem E-Mail-Kanal. Wenn Ihr Team-Platz nur seine eigenen Kontakte sehen kann und der bestehende Kontakt nicht dazu gehört, wird die ID weggelassen; suchen Sie stattdessen mit Kontakt per Telefon oder E-Mail abrufen danach.
Äquivalente WhatsApp-Schreibweisen zählen als dieselbe Nummer. Einige Länder haben zwei gültige Schreibweisen für dieselbe Mobilfunkleitung, und WhatsApp meldet möglicherweise eine von beiden: Mexiko (
+52…und die ältere+521…), Brasilien (mit oder ohne die neunte Ziffer) und Argentinien (mit oder ohne die9nach der+54). Die Duplikatprüfung bei der Erstellung undGET /contacts?phoneNumber=erfolgt über beide Schreibweisen hinweg, sodass Sie den bestehenden Kontakt zurückerhalten, egal welche Form Sie senden. Die auf dem Kontakt gespeichertephone_numberwird niemals überschrieben.
Kontakt per Telefon oder E-Mail abrufen
GET /contacts?phoneNumber=... oder GET /contacts?email=...
Sucht einen einzelnen Kontakt und gibt das vollständige, angereicherte Kontaktobjekt zurück – einschließlich seiner Listen, Tags und Kampagnen, die in { id, name }-Paare aufgelöst wurden, sowie der letzten ausgetauschten Nachricht.
Übergeben Sie entweder phoneNumber (im internationalen Format) oder email. Wenn Sie keines von beiden übergeben, schaltet dieser Endpunkt stattdessen in den Modus Kontakte auflisten um.
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"])
Antwort
{
"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 ist der Klick auf eine Anzeige, der zu Ihrer Website geführt hat und diesem Kontakt durch das Anzeigenklick-Skript zugeordnet wurde, oder null, wenn kein solcher vorhanden ist. Die Felder werden unter Anzeigenklick-Attribution für WhatsApp erläutert.
Die Kontakt-ID wird sowohl auf der obersten Ebene (contactId) als auch innerhalb des Objekts (contact.id) zurückgegeben. Wenn keine Übereinstimmung gefunden wird, erhalten Sie einen 404 mit { "success": false, "message": "Contact not found" }.
avatarUrlist das Profilfoto des Kontakts, das von WhatsApp oder Meta übernommen wird, wenn dieser Ihnen eine Nachricht sendet. Es ist schreibgeschützt: Sie können es nicht festlegen, und es istnullfür Kontakte, die kein Foto haben oder die Sie über einen Kanal erreichen, der kein Foto bereitstellt. Betrachten Sie den Link als temporär, anstatt ihn zu speichern, da einige dieser Fotolinks ablaufen und automatisch aktualisiert werden. (Im Listen-Endpunkt unten wird derselbe Wert alsavatar_urlbezeichnet.)
Telefonnummern in URLs. Ein
+-Zeichen in einer Abfragezeichenfolge muss als%2BURL-kodiert sein, da es sonst als Leerzeichen gelesen wird. Die obigen Beispiele erledigen dies für Sie.
Kontakte, deren Nummer verborgen ist
Ein WhatsApp Web-Kontakt kann ohne Telefonnummer eintreffen, wenn WhatsApp diese dem verknüpften Gerät vorenthält (siehe Kontakte, deren Nummer verborgen ist). Jeder Kontakt, den Sie lesen, enthält hierfür zwei zusätzliche Felder: number_hidden (numberHidden in der Einzelkontakt-Form) und whatsapp_lid (whatsappLid).
- Bei einem Kontakt mit verborgener Nummer ist
phone_numbergleichnull,number_hiddenisttrueundwhatsapp_lidenthält die interne ID von WhatsApp im Format153055538446346@lid. Dies ist keine wählbare Nummer. Ordnen Sie den Kontakt anhand dieser ID aus Ihrem eigenen System zu und übergeben Sie sie alsphoneNumberan diese Suche, um den Kontakt erneut zu finden. - Bei allen anderen Kontakten ist
number_hiddengleichfalseundwhatsapp_lidist die ID, die WhatsApp für den Kontakt gemeldet hat, odernull.
Ausgehende Webhooks und Automatisierungs-Payloads, die einen Kontakt enthalten, führen dieselben drei Felder, und der CSV-Export der Kontakte enthält neben der Telefonnummer eine Spalte für „Nummer verborgen“ und eine für die WhatsApp-LID. Sobald WhatsApp die echte Nummer freigibt, aktualisiert sich der Kontakt von selbst und phone_number wird ausgefüllt.
Einen Kontakt per ID abrufen
GET /contacts/{contactId}
Wenn Sie die ID eines Kontakts bereits haben, können Sie ihn direkt abrufen. Die Antwortstruktur ist identisch mit der obigen Suche.
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"])
Eine Kontakt-ID, die in Ihrem Konto nicht existiert, gibt einen 404 zurück.
Kontaktstatistiken abrufen
GET /contacts/{contactId}/stats
Gibt aggregierte Nachrichtenstatistiken für einen Kontakt zurück: Summen, KI- vs. menschliche Antworten, verbrauchte Credits sowie Zeitstempel der ersten und letzten Nachricht.
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"])
Antwort
{
"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 ist derselbe KI-Nachrichtenzähler, den die „Zurücksetzen“-Schaltfläche in der App für einen Kontakt auf Null setzt. creditsUsed ist der laufende Credit-Gesamtstand für diesen Kontakt, nicht nur die Zahlen dieser Antwort. Eine Kontakt-ID, die in Ihrem Konto nicht existiert, gibt einen 404 zurück.
Kontaktkosten abrufen
GET /contacts/{contactId}/cost
Gibt die Credits zurück, die ein Kontakt verbraucht hat, aufgeschlüsselt nach Unterhaltung (Chat-Sitzung), nach Art der Aktion sowie die durchschnittlichen Kosten einer Unterhaltung, die die KI allein geführt hat, im Vergleich zu einer, bei der Ihr Team eingegriffen hat. Verwenden Sie dies, um einem Kunden die Kosten einer Unterhaltung aufzuzeigen.
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"])
Antwort
{
"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
}
Feldhinweise:
total_creditszählt jede Belastung für den Kontakt (KI-Antworten, Tool-Aufrufe, Tags, Follow-ups, Zusammenfassungen, Hintergrundbewertungsschritte, Vorlagen- und Zustellungsgebühren), wobei Rückerstattungen für den Kontakt abgezogen werden. Credit-Zuweisungen, Aufladungen und Verlängerungen gehören nie zu einem Kontakt. Testläufe im Playground werden nicht berücksichtigt.- Eine Belastung fällt in die Unterhaltung, in deren Zeitfenster sie fällt. Ein Fenster läuft vom Beginn der Unterhaltung bis zu deren Abschluss oder bis die nächste Unterhaltung beginnt, sodass keine Belastung doppelt gezählt wird. Belastungen außerhalb jedes Fensters befinden sich in
unattributed_credits(und in der Gesamtsumme). outcome:containedbedeutet, dass die KI geantwortet hat und niemand aus Ihrem Team eingreifen musste;handed_offbedeutet, dass jemand eine Nachricht gesendet hat, nachdem die KI geantwortet hatte, oder die KI einen Menschen alarmiert hat;no_aibedeutet, dass die KI in dieser Unterhaltung nie geantwortet hat.- Es werden bis zu 200 Unterhaltungen aufgelistet, beginnend mit der neuesten;
sessions_truncatedisttrue, wenn es mehr gibt. - Geben Sie für einen Agenturkunden
sub_account_idan; die Zahlen werden in den eigenen Credits dieses Kunden angegeben. creditsUsedunter Kontaktstatistiken abrufen ist ein laufender Zähler, der für den Kontakt geführt wird. Dieser Endpunkt berechnet den Wert aus dem Credit-Hauptbuch neu, daher können die beiden Werte leicht voneinander abweichen, meist bei älteren Kontakten.- Teammitglieder benötigen die Berechtigung für die Abrechnung. Ein Kontakt, der nicht in Ihrem Konto vorhanden ist, gibt
404zurück;503bedeutet, dass die Zahlen derzeit nicht berechnet werden können; versuchen Sie es in Kürze erneut.
Kontakte auflisten
GET /contacts
Rufen Sie GET /contacts ohne phoneNumber und email auf, um durch alle Ihre Kontakte zu blättern, beginnend mit den neuesten. Jede Seite gibt kompakte Kontaktzusammenfassungen zurück (Listen, Tags und Kampagnen werden als ID-Arrays anstelle von vollständigen Objekten zurückgegeben) sowie einen next_cursor.
| Abfrageparameter | Beschreibung |
|---|---|
limit |
Seitengröße. Standardwert ist 50, Maximum 100. |
cursor |
Der next_cursor-Wert von der vorherigen Seite. Auf der ersten Seite weglassen. |
listId |
Optional. Nur Kontakte zurückgeben, die zu dieser Liste gehören. |
Um alle Seiten zu durchlaufen: Führen Sie den ersten Aufruf ohne Cursor aus und übergeben Sie dann den zurückgegebenen next_cursor als cursor. Stoppen Sie, wenn next_cursor gleich null ist – das bedeutet, dass es keine weiteren Ergebnisse gibt.
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
Antwort
{
"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"
}
Jeder Kontakt enthält ad_attribution: den Klick auf eine Anzeige, der zu Ihrer Website geführt hat und dem Kontakt zugeordnet wurde, mit denselben Feldern wie adAttribution unter Kontakt per ID abrufen, oder null, wenn kein solcher vorhanden ist.
Hinweis: Das Filtern nach einem listId, das in Ihrem Konto nicht existiert, gibt ein 404 zurück. Ein ungültiges cursor gibt ein 400 zurück.
Kontakte zählen
GET /contacts/count
Gibt zurück, wie viele Kontakte einem Filter entsprechen, inklusive einer Aufschlüsselung nach Kanal, ohne durch die Seiten blättern zu müssen. Dies ist der richtige Aufruf für jede „Wie viele“-Frage – für ein Dashboard-Element, eine Automatisierung oder eine Anfrage an Champ. Alle Filter sind optional, und die Kombination mehrerer Filter schränkt die Anzahl ein (ein Kontakt muss auf jeden von Ihnen gesendeten Filter zutreffen).
| Abfrageparameter | Beschreibung |
|---|---|
agentId |
Nur Kontakte, die diesem KI-Agenten zugewiesen sind. Übergeben Sie none für Kontakte ohne zugewiesenen Agenten (diese werden vom Standard-Agenten des Kanals beantwortet). |
channel |
Nur Kontakte auf diesem Kanal, z. B. whatsapp, messenger, instagram, sms, email, chat_widget. |
tag |
Nur Kontakte mit diesem Tag, anhand des Tag-Namens (Groß-/Kleinschreibung spielt keine Rolle). Ein Tag-Name, den Sie nicht haben, gibt 404 zurück. |
listId |
Nur Kontakte auf dieser Liste. |
botActive |
true oder false – nur Kontakte, deren KI-Assistent aktiviert oder deaktiviert ist. |
status |
Nur Kontakte mit diesem Status, z. B. Lead. |
rules |
Ein URL-kodiertes JSON-Regelobjekt, das dieselbe Struktur wie eine intelligente Liste verwendet (siehe Die smart_rules-Struktur weiter unten). Kann nicht mit den anderen Filtern kombiniert werden. |
Senden Sie gar keinen Filter, erhalten Sie die Gesamtzahl der Kontakte in Ihrem 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"])
Antwort
{
"success": true,
"total": 3423,
"by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
"filters": { "agentId": "agent_xyz789" }
}
by_channel schlüsselt dieselbe Gesamtzahl nach Kanal auf; Kontakte, die keinem Kanal zugeordnet sind, werden unter none gezählt. filters spiegelt die angewendeten Filter wider, sodass Sie überprüfen können, ob der Aufruf das gewünschte Ergebnis erzielt hat.
Hinweis: Das Senden von rules zusammen mit einem anderen Filter oder einem rules-Wert, der kein gültiges JSON ist, führt zu 400. Ein Tag-Name oder eine Listen-ID, die in Ihrem Konto nicht existiert, führt zu 404.
Kontakt aktualisieren
PUT /contacts/{contactId}
Aktualisiert einen bestehenden Kontakt. Nur die Felder, die Sie angeben, werden geändert – lassen Sie alles weg, was Sie nicht ändern möchten. Sie müssen mindestens ein Feld senden, andernfalls erhalten Sie eine 400 („Keine Felder zum Aktualisieren“).
| Feld | Beschreibung |
|---|---|
firstName |
Vorname. |
lastName |
Nachname. |
email |
E-Mail-Adresse. |
is_bot_active |
Legt fest, ob der KI-Assistent auf diesen Kontakt antwortet. |
is_private |
Als privat markieren. Wenn dies auf true gesetzt wird, wird auch der KI-Assistent deaktiviert. |
do_not_disturb |
Automatische Kontaktaufnahme mit diesem Kontakt pausieren. Stoppt auch die KI-Antworten. |
follow_ups_disabled |
Alle automatischen Follow-ups für diesen Kontakt stoppen (Quick, Cycle und Cold-Lead), während die KI weiterhin auf Nachrichten antwortet. Nützlich, sobald jemand gekauft hat. Bleibt deaktiviert, bis Sie es wieder auf false setzen. |
lead_profile |
Freitext-Notizen zum Lead. |
custom_fields |
Ein Objekt mit benutzerdefinierten Feldern. Wird pro Schlüssel zusammengeführt – nur die gesendeten Schlüssel werden geschrieben, die restlichen bestehenden benutzerdefinierten Felder bleiben erhalten. Sie können benutzerdefinierte Feld-Schlüssel auch auf der obersten Ebene übergeben. Typisierte Felder werden validiert; ein ungültiger Wert führt zur Ablehnung der Anfrage mit field_errors – siehe Benutzerdefinierte Feldtypen. |
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"])
Antwort
{
"success": true,
"message": "Contact updated successfully"
}
Benutzerdefinierte Felder werden zusammengeführt, nicht ersetzt. Das Senden von
{ "custom_fields": { "tier": "gold" } }setzt nurtier– alle anderen benutzerdefinierten Felder des Kontakts bleiben unverändert. Um ein benutzerdefiniertes Feld vollständig für alle Kontakte zu entfernen, verwenden Sie Benutzerdefiniertes Feld löschen.
Tags hinzufügen oder entfernen
POST /contacts/{contactId}/tags
Fügt Tags zu einem einzelnen Kontakt hinzu und/oder entfernt sie in einem einzigen Aufruf. Übergeben Sie Tag-IDs in addTagIds und removeTagIds. Mindestens eines der beiden Felder darf nicht leer sein.
Die Tags müssen bereits in Ihrem Konto existieren – erstellen Sie diese zuerst über den Tags-Endpunkt. Wenn der Kontakt oder ein referenzierter Tag nicht existiert, erhalten Sie eine 404.
| Feld | Beschreibung |
|---|---|
addTagIds |
Array von Tag-IDs, die dem Kontakt hinzugefügt werden sollen. |
removeTagIds |
Array von Tag-IDs, die vom Kontakt entfernt werden sollen. |
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"])
Antwort
{
"success": true,
"contact_id": "contact_abc123",
"added": 1,
"removed": 1
}
Ihre Tag-Bibliothek verwalten
Diese Endpunkte verwalten ein Tag selbst – also das Umbenennen oder Löschen in Ihrem Konto – im Gegensatz zum Hinzufügen oder Entfernen eines Tags bei einem Kontakt (siehe Tags hinzufügen oder entfernen oben). Jedes Tag in Ihrem Konto hat eine ID (tagId): diejenige, die im Tag-Manager Ihres Dashboards angezeigt wird, und diejenige, die als tag_id auf der obersten Ebene der Antwort zurückgegeben wird, wenn Sie ein Tag mit POST /tags und einem JSON-Body von { "name": "..." } erstellen (kein phoneNumber, email oder contactId).
Ein Tag aktualisieren
PUT /tags/{tagId}
Senden Sie nur die Felder, die Sie ändern möchten.
| Feld | Beschreibung |
|---|---|
name |
Der Name des Tags. |
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)" }'
Antwort
{ "success": true, "tag_id": "tagHotLead" }
Ein tagId, das in Ihrem Konto nicht existiert, gibt einen 404 zurück.
Ein Tag löschen
DELETE /tags/{tagId}
Löscht ein Tag anhand der ID. Dies kann nicht rückgängig gemacht werden — Kontakte, die dieses Tag tragen, verlieren es einfach. Das Löschen eines Tags, das bereits entfernt wurde (oder nie existierte), gibt 200 mit deleted: 0 zurück anstelle eines 404, da es nichts aufzulisten gibt.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagColdLead?apiKey=YOUR_API_KEY"
Antwort
{ "success": true, "deleted": 1 }
Mehrere Tags gleichzeitig löschen
DELETE /tags
| Feld | Beschreibung |
|---|---|
tagIds |
Array der zu löschenden Tag-IDs (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"] }'
Antwort
{ "success": true, "deleted": 2 }
IDs, die nicht existieren oder zu einem anderen Konto gehören, werden stillschweigend übersprungen und nicht in deleted gezählt.
Flag massenhaft setzen
POST /contacts/bulk-flag
Setzt ein boolesches Flag für viele Kontakte gleichzeitig. Bis zu 500 Kontakt-IDs pro Anfrage. IDs, die in Ihrem Konto nicht existieren, werden übersprungen und in skipped gezählt.
| Feld | Beschreibung |
|---|---|
contactIds |
Array von Kontakt-IDs, die aktualisiert werden sollen (max. 500). |
field |
Welches Flag gesetzt werden soll. Eines von bot_active (KI-Assistent ein/aus), dnd (automatisierte Kontaktaufnahme pausieren), spam, private. |
value |
Der boolesche Wert, auf den das Flag gesetzt werden soll. |
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"])
Antwort
{
"success": true,
"updated": 2,
"skipped": 0
}
Kontakte massenhaft importieren
POST /contacts/import
Erstellt bis zu 500 Kontakte in einem Aufruf aus einem JSON-Array. Jeder Datensatz benötigt eine phone_number im internationalen Format; alles andere ist optional. Datensätze mit ungültigen Telefonnummern oder nicht unterstützten Kanälen werden übersprungen (nicht erstellt), und jeder übersprungene Datensatz wird mit seinem Index und dem Grund gemeldet – so können Sie nur die Fehler beheben und es erneut versuchen.
Telefonnummern, die bereits in Ihrem Konto vorhanden sind, werden standardmäßig als duplicate übersprungen – wenn Sie jedoch eine listId senden, wird der bereits vorhandene Kontakt dennoch dieser Liste hinzugefügt und unter added_to_list gezählt, sodass ein erneuter Import die Liste füllt, ohne etwas am Kontakt zu ändern. Senden Sie updateExisting: true, um diese Kontakte stattdessen zu aktualisieren: Die im Datensatz vorhandenen Felder überschreiben die des Kontakts (first_name, last_name, email, lead_profile und custom_fields werden Schlüssel für Schlüssel zusammengeführt), tags werden hinzugefügt und der Kontakt wird zu listId hinzugefügt. Kanal, Telefonnummer und Bot-Flags werden bei einem bestehenden Kontakt niemals geändert.
Sie können optional jeden importierten (oder aktualisierten) Kontakt mit listId zu einer Liste hinzufügen, einen defaultChannel für Datensätze festlegen, die keinen angeben, und Datensätze mit tags markieren (Tag-Namen – fehlende Tags werden erstellt, bestehende werden unabhängig von der Groß-/Kleinschreibung abgeglichen).
Felder auf oberster Ebene
| Feld | Erforderlich | Beschreibung |
|---|---|---|
contacts |
Ja | Array von Kontaktdatensätzen (max. 500). |
listId |
Nein | Liste, zu der jeder Kontakt in dieser Anfrage hinzugefügt werden soll – erstellt, aktualisiert sowie die als Duplikate übersprungenen. Muss eine Liste in Ihrem Konto sein. |
defaultChannel |
Nein | Kanal, der auf Datensätze angewendet wird, bei denen channel fehlt. Einer der Werte whatsapp, sms, whatsapp_web. Standardmäßig whatsapp. |
updateExisting |
Nein | true, um Kontakte zu aktualisieren, deren Telefonnummer bereits existiert, anstatt sie als duplicate zu überspringen. Standardmäßig false. |
Felder pro Datensatz
| Feld | Erforderlich | Beschreibung |
|---|---|---|
phone_number |
Ja | Telefonnummer im internationalen Format (ein führendes + wird hinzugefügt, falls es fehlt). |
first_name |
Nein | Vorname. |
last_name |
Nein | Nachname. |
email |
Nein | E-Mail-Adresse. |
channel |
Nein | Einer der Werte whatsapp, sms, whatsapp_web. Greift auf defaultChannel zurück. |
is_bot_active |
Nein | Ob der KI-Assistent antwortet. Standardmäßig true. |
is_private |
Nein | Als privat markieren. Standardmäßig false. |
lead_profile |
Nein | Freitext-Notizen zum Lead. |
custom_fields |
Nein | Objekt mit benutzerdefinierten Feld-Schlüsseln und -Werten. |
tags |
Nein | Array von Tag-Namen (ein einzelner "a; b"-String funktioniert ebenfalls). Tags, die nicht existieren, werden erstellt; bestehende werden unabhängig von der Groß-/Kleinschreibung abgeglichen. Max. 25 pro Datensatz. |
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'])}")
Antwort
{
"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": []
}
Wenn einige Datensätze nicht erstellt werden können, erscheinen sie in skipped mit dem Grund (hier ohne updateExisting, daher wird die existierende Nummer übersprungen):
{
"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" }
]
}
Die übersprungene Zeile wurde dennoch listId hinzugefügt, was added_to_list zählt – nichts anderes an diesem Kontakt wurde verändert. Mit updateExisting: true meldet dieselbe Anfrage den bestehenden Kontakt stattdessen unter updated / updated_contact_ids.
Mögliche Gründe für das Überspringen: invalid_record, missing_phone_number, invalid_phone_number, invalid_channel, duplicate_in_request, duplicate, contact_limit_reached, create_failed.
Tariflimits. Wenn das Kontaktlimit Ihres Tarifs diese Anzahl neuer Kontakte nicht zulässt, wird die gesamte Anfrage vorab mit einem
403abgelehnt. Wenn das Limit während des Vorgangs erreicht wird, werden die verbleibenden Datensätze mit dem Grundcontact_limit_reachedals übersprungen zurückgegeben.
Kontakte aus einer CSV-Datei importieren
Für Importe, die größer sind als das, was der Massenimport unterstützt (bis zu etwa 50.000 Zeilen), stellen Sie einen asynchronen Importauftrag für eine CSV-Datei in die Warteschlange, die sich bereits im Speicher Ihres Kontos befindet, und fragen Sie diesen ab, bis er abgeschlossen ist.
Import starten
POST /contacts/import-csv
| Feld | Erforderlich | Beschreibung |
|---|---|---|
csvStoragePath |
Ja | Speicherpfad der CSV-Datei unter users/{your account id}/imports/, endend auf .csv. |
listName |
Ja | Erstellt (oder verwendet) eine Liste mit diesem Namen und fügt jeden importierten Kontakt hinzu. |
existingListRefs |
Nein | Array bestehender Listen-IDs, denen jeder importierte Kontakt ebenfalls hinzugefügt werden soll. |
defaultChannel |
Nein | Kanal, der auf Zeilen angewendet wird, die keinen angeben. |
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"]
Antwort (202 — der Import ist in der Warteschlange, noch nicht abgeschlossen)
{
"success": true,
"job_id": "csvimp_abc123",
"status": "queued"
}
Die Datei in den Speicher bringen. Dieser Endpunkt startet und verfolgt den Importauftrag; er akzeptiert selbst keinen Upload. Die CSV-Datei muss sich bereits unter
csvStoragePathbefinden, bevor Sie ihn aufrufen – der CSV-Importer des Dashboards erledigt dies als ersten Schritt.
Den Import-Job abfragen
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"
Antwort
{
"success": true,
"job_id": "csvimp_abc123",
"status": "completed",
"imported": 812,
"updated": 0,
"skipped": 14,
"errors": [],
"error_message": null
}
status durchläuft queued → processing → completed oder failed mit dem Grund in error_message. Eine jobId, die nicht in Ihrem Konto existiert, gibt einen 404 zurück.
Kontakte exportieren
Startet einen asynchronen CSV-Export Ihrer Kontakte und gibt einen Auftrag zurück, den Sie auf Abschluss abfragen können.
Export starten
POST /contacts/export
| Feld | Erforderlich | Beschreibung |
|---|---|---|
listId |
Nein | Exportiert nur Kontakte, die zu dieser Liste gehören. |
contactIds |
Nein | Exportiert nur diese spezifischen Kontakt-IDs. |
Wenn beide Felder leer gelassen werden, werden alle Kontakte Ihres Kontos exportiert.
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"]
Antwort (202 — der Export ist in der Warteschlange)
{
"success": true,
"job_id": "export_abc123",
"status": "queued"
}
Export-Job abfragen
GET /contacts/export/{jobId}
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/export/export_abc123?apiKey=YOUR_API_KEY"
Antwort
{
"success": true,
"job_id": "export_abc123",
"status": "completed",
"export_id": "exp_xyz789",
"contact_count": 812,
"error_message": null
}
Sobald
status"completed"ist, erhalten Sieexport_idundcontact_count. Die heruntergeladene CSV-Datei finden Sie auf der Export-Seite Ihres Dashboards.
Nachricht an einen Kontakt senden
POST /contacts/{contactId}/send-message
Sendet eine Nachricht an einen bestehenden Kontakt über den Kanal, den dieser bereits nutzt. Die Nachricht wird in die Warteschlange gestellt und im Hintergrund zugestellt – die Antwort bestätigt lediglich, dass sie akzeptiert wurde, nicht, dass sie bereits zugestellt ist.
| Feld | Erforderlich | Beschreibung |
|---|---|---|
body |
Ja | Der Text der zu sendenden Nachricht. |
mediaUrl |
Nein | URL einer Mediendatei zum Anhängen. |
mediaContentType |
Nein | MIME-Typ der angehängten Medien (z. B. 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"])
Antwort
{
"success": true,
"messageId": "aB3dE5fG7hI9jK1lM2nO",
"contactId": "contact_abc123",
"channel": "whatsapp",
"message": "Message created successfully. Delivery is being processed."
}
Kann gerade nicht gesendet werden? Wenn der Kontakt den „Nicht stören“-Modus oder den privaten Modus aktiviert hat oder sich auf keinem Kanal befindet, der ausgehende Nachrichten empfangen kann, wird die Anfrage mit einem
422und einer erklärendenerrorabgelehnt.
Informationen zum Senden per Telefonnummer, Instagram-ID oder einer anderen Kanalidentität anstelle einer Kontakt-ID – sowie weitere allgemeine Informationen zum Messaging – finden Sie in der Messages API.
Senden Sie ein KI-Follow-up an einen Kontakt
POST /contacts/{contactId}/ai-follow-up
Lässt einen KI-Agenten eine Nachricht in seiner eigenen Stimme verfassen, basierend auf dem bisherigen Gesprächsverlauf und einer von Ihnen gegebenen Anweisung, und sendet diese über den Kanal des Kontakts. Dies entspricht dem Automatisierungsschritt KI-Follow-up senden und kostet die gleichen Credits wie ein KI-Follow-up.
| Feld | Erforderlich | Beschreibung |
|---|---|---|
instruction |
Ja | Was die Nachricht bewirken soll, in einfachen Worten, bis zu 2.000 Zeichen. Zum Beispiel: “Erinnere sie daran, dass ihr reservierter Link heute Abend abläuft, und frage, ob sie ihn sichern möchten”. |
agentId |
Nein | Der Agent, der die Nachricht schreibt. Lassen Sie dies weg, um den Agenten zu verwenden, der den Kontakt bereits betreut. |
mustContain |
Nein | Eine Liste von bis zu 5 Phrasen oder Links (jeweils bis zu 500 Zeichen), die die Nachricht wortwörtlich enthalten muss. Wenn die KI eine davon auslässt, wird nichts gesendet und skipReason ist text_check_failed. |
respectMessagingWindow |
Nein | Standard true. Bei WhatsApp Business API, Instagram und Messenger: Überspringen, wenn die letzte Nachricht des Kontakts älter als 24 Stunden ist. |
skipWhenAiPaused |
Nein | Standard true. Überspringen, wenn die KI für diesen Kontakt ausgeschaltet ist. |
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);
Antwort, wenn die Nachricht gesendet wurde:
{
"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"
}
Antwort, wenn sie übersprungen wurde:
{
"sent": false,
"skipReason": "window_closed"
}
Beide geben den Status 200 zurück. skipReason ist einer der Werte no_agent (kein Agent bearbeitet den Kontakt und es wurde keiner angegeben), dnd (Nicht stören), ai_paused, window_closed (außerhalb des 24-Stunden-Fensters oder der Kontakt hat Ihnen auf diesem Kanal nie geschrieben), no_credits, text_check_failed (ein mustContain-Element fehlte), no_text (die KI hat nichts Verwendbares geschrieben) oder linkedin_gap (ein LinkedIn-Lead hat vor weniger als 24 Stunden eine automatische Nachricht erhalten; die Antwort enthält dann auch nextAllowedAt, den Zeitpunkt, zu dem die nächste Nachricht gesendet werden darf). Ein Überspringen ist eine normale Antwort, kein Fehler. Überprüfen Sie daher sent, bevor Sie davon ausgehen, dass die Nachricht gesendet wurde. Ein übersprungener Aufruf verbraucht keine Credits.
Ein Body, dem instruction fehlt oder der ein Feld mit dem falschen Typ enthält, erhält einen 400. Ein Kontakt oder Agent, der nicht in Ihrem Konto vorhanden ist, erhält einen 404. Fehler werden als { "success": false, "error": "..." } zurückgegeben. Der API-Schlüssel eines Teammitglieds benötigt Bearbeitungszugriff auf Kontakte.
Einen KI-Agenten einem Kontakt zuweisen
POST /contacts/{contactId}/assign-agent
Verschiebt eine bestehende Unterhaltung ab der nächsten Nachricht zu einem anderen KI-Agenten. Dies entspricht der Funktion KI-Agent zuweisen im Chat-Menü und ist derselbe Schritt, den die Aktion KI-Agent zuweisen in Automatisierungen verwendet.
| Feld | Erforderlich | Beschreibung |
|---|---|---|
agentId |
Ja | Die ID des KI-Agenten, der übernehmen soll, oder null, um die Zuweisung aufzuheben, damit die Konversation zurück in Ihren Team-Posteingang geht. |
triggerAIResponse |
Nein | true veranlasst den neu zugewiesenen Agenten, sofort auf die neuesten unbeantworteten Nachrichten des Kontakts zu antworten. Der Standardwert ist false. Wenn der Kontakt bereits diesem Agenten zugewiesen war und dessen letzte Nachricht bereits beantwortet wurde, wird keine Antwort gestartet: Die Antwort enthält aiResponseTriggered: false und einen aiTriggerError, der den Grund angibt. |
Vorsicht bei
triggerAIResponse: true– es sendet dem Kontakt sofort eine Nachricht. Verwenden Sie es daher nur, wenn Sie möchten, dass der Kontakt jetzt kontaktiert wird. Bei Messenger und Instagram schlägt diese Nachricht fehl, wenn der Kontakt Ihnen zuletzt vor mehr als 24 Stunden geschrieben hat.
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"])
Antwort
{
"success": true,
"data": {
"contactId": "contact_abc123",
"agentId": "agent_xyz789",
"aiResponseTriggered": false
}
}
Der Agent muss zum selben Konto gehören wie der Kontakt; andernfalls wird die Anfrage mit einem
404oder403abgelehnt. Agenten-IDs finden Sie auf der Seite „KI-Agenten“ (die URL jedes Agenten endet mit seiner ID).
KI-Agent vielen Kontakten zuweisen
POST /contacts/bulk-assign-agent
Verschiebt viele Konversationen in einem Aufruf zu einem anderen KI-Agenten – oder löscht die Zuweisung für alle mit null. Es handelt sich rein um eine Routing-Änderung: Es wird keine Nachricht gesendet und der Agent antwortet niemandem. Jeder Kontakt erhält einfach den neuen Agenten, wenn er das nächste Mal schreibt. (Deshalb gibt es hier kein triggerAIResponse.)
| Feld | Erforderlich | Beschreibung |
|---|---|---|
agentId |
Ja | Der KI-Agent, der übernehmen soll, oder null, um die Zuweisung zu löschen. |
contactIds |
Eines der drei | Bis zu 500 Kontakt-IDs zum Verschieben. |
filter |
Eines der drei | Wählen Sie die Kontakte auf dem Server aus, anstatt sie aufzulisten, beginnend mit den neuesten. Verwendet dieselben Schlüssel wie die Filter des Zähl-Endpunkts: agentId (oder none), channel, tag, listId, botActive, status. |
rules |
Eines der drei | Ein Regelobjekt für intelligente Listen – siehe Die smart_rules-Struktur. |
limit |
Nein | Wie viele Kontakte in diesem Aufruf verschoben werden sollen, wenn Sie mit filter oder rules auswählen. 1 bis 500, Standardwert ist 500. |
Senden Sie genau eines von contactIds, filter oder 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"])
Antwort
{
"success": true,
"agentId": "agent_xyz789",
"matched": 3415,
"updated": 500,
"skipped": 0,
"remaining": 2915,
"filters": { "agentId": "agent_abc123" }
}
matched ist die Anzahl der Kontakte, die die Auswahl insgesamt gefunden hat, updated wie viele durch diesen Aufruf verschoben wurden, skipped wie viele der von Ihnen gesendeten IDs in Ihrem Konto nicht gefunden wurden und remaining wie viele nach Abschluss dieses Aufrufs noch übereinstimmen.
Alle verschieben. Da ein Aufruf maximal 500 Kontakte verschiebt, erfordert eine große Gruppe mehrere Aufrufe. Verwenden Sie einen Filter, der nicht mehr auf einen Kontakt zutrifft, sobald er verschoben wurde – zum Beispiel filter: { "agentId": "agent_abc123" } bei der Zuweisung zu agent_xyz789 – und wiederholen Sie genau denselben Aufruf, bis remaining als 0 zurückgegeben wird. Wenn Sie stattdessen contactIds übergeben, ist remaining immer 0.
Kontakt einer Abteilung zuweisen
POST /contacts/{contactId}/department
“Diesen Lead dem Vertrieb zuweisen” — ordnet einen Kontakt einer benannten Abteilung zu und weist ihn standardmäßig der Person in dieser Abteilung zu, die aktuell die wenigsten Kontakte hat. Dies ist unabhängig von der Zuweisung eines KI-Agenten: Eine Abteilung beantwortet die Frage „Welches Team ist zuständig?“, ein Agent beantwortet die Frage „Welche KI antwortet hier?“, und das Festlegen des einen löscht niemals das andere.
| Feld | Erforderlich | Beschreibung |
|---|---|---|
department_id |
Ja | Die Abteilung, der der Kontakt zugeordnet werden soll. Übergeben Sie null, um die Zuordnung aufzuheben. |
hand_to_member |
Nein | Weist den Kontakt zusätzlich der Person in der Abteilung mit der geringsten Auslastung zu. Standardwert ist true. Kontakte, die bereits jemandem gehören, werden nicht neu zugewiesen. |
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"])
Antwort
{
"success": true,
"department_id": "dept_sales",
"assigned_to": "member_uid_123"
}
assigned_to ist null, wenn der Kontakt bereits jemandem gehörte oder Sie hand_to_member: false übergeben haben.
Kontakt über Kanäle hinweg verknüpfen
“Auf WhatsApp fortfahren” (oder SMS) sucht oder erstellt den Kontakt dieser Person auf einem anderen telefonbasierten Kanal und verknüpft beide miteinander, sodass der Rest der App sie als dieselbe Person erkennt.
Mit einem anderen Kanal verknüpfen
POST /contacts/{contactId}/link-channel
| Feld | Erforderlich | Beschreibung |
|---|---|---|
channel |
Ja | Der Kanal, mit dem verknüpft werden soll. Einer der Werte whatsapp, whatsapp_web, sms. |
phoneNumber |
Nein | Telefonnummer, die für den neuen Kanal verwendet werden soll. Standardmäßig die eigene Nummer des Quellkontakts. |
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" }'
Antwort
{
"success": true,
"data": {
"contact_id": "contact_def456",
"person_id": "person_xyz789",
"created": true
}
}
created gibt an, ob für den Zielkanal ein neuer Kontakt erstellt oder ein bestehender gefunden und verknüpft wurde. Ein zweiter Aufruf ist sicher – er gibt denselben contact_id mit created: false zurück, anstatt ein Duplikat zu erstellen.
Ein 422 bedeutet, dass das Konto diese Verknüpfung derzeit nicht durchführen kann: Der Kontakt befindet sich bereits in dieser Kanalfamilie, hat keine zu verwendende Telefonnummer oder es gibt keinen verbundenen Absender für den Zielkanal. Ein 409 bedeutet, dass die beiden Kontakte bereits mit zwei verschiedenen Personen verknüpft sind – heben Sie zuerst eine Verknüpfung auf.
Verknüpfte Konversationen eines Kontakts auflisten
GET /contacts/{contactId}/linked
Gibt die anderen Konversationen zurück, die dieselbe Person wie dieser Kontakt sind. Ein nicht verknüpfter Kontakt gibt ein leeres Array zurück, keinen 404 – „diese Person hat keine anderen Kanäle“ ist ein normaler Zustand.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/linked?apiKey=YOUR_API_KEY"
Antwort
{
"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"
}
}
]
}
Verknüpfung eines Kontakts aufheben
DELETE /contacts/{contactId}/link
Entfernt diesen Kontakt einseitig aus seiner Person – alle anderen Kontakte, die noch mit dieser Person verknüpft sind, behalten ihre Verknüpfung, sodass das Aufheben einer von drei Verknüpfungen die Gruppe nicht auflöst.
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/link?apiKey=YOUR_API_KEY"
Antwort
{ "success": true }
Profilbild eines Kontakts abrufen
POST /contacts/{contactId}/profile-pic
Ruft (und zwischenspeichert) das WhatsApp- oder Meta-Profilfoto des Kontakts bei Bedarf ab – dasselbe Foto, das als avatarUrl unter Kontakt abrufen zurückgegeben wird, jedoch aktualisiert.
curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/profile-pic?apiKey=YOUR_API_KEY"
Antwort
{
"success": true,
"avatar_url": "https://example.com/photo.jpg",
"cached": false
}
cached: true bedeutet, dass die URL aus einem kürzlichen Abruf stammt und nicht aus einer neuen Anbieterabfrage – Bilder werden 7 Tage lang zwischengespeichert, und ein Kontakt, für den der Anbieter kein erreichbares Foto meldet, wird 24 Stunden lang als nicht verfügbar zwischengespeichert. Wenn kein Bild abgerufen werden kann, wird avatar_url weggelassen und message erklärt den Grund.
Kontakte automatisch mit KI taggen
Führt die Tag-Regeln Ihres Kontos auf den vollständigen Konversationsverlauf eines oder mehrerer Kontakte aus und wendet Tags an (oder entfernt sie) – genau wie beim Echtzeit-Tagging während eines Live-Chats. Es gelten dieselben Regeln und dieselben Kreditkosten pro Tag.
Einen Durchlauf starten
POST /contacts/auto-tag
| Feld | Erforderlich | Beschreibung |
|---|---|---|
scope |
Ja | "contacts", um bestimmte Kontakte zu taggen, oder "agent", um jede Konversation zu taggen, die derzeit von einem KI-Agenten bearbeitet wird. |
contact_ids |
Erforderlich, wenn scope gleich "contacts" ist |
Array von Kontakt-IDs, 1 bis 500. |
agent_id |
Erforderlich, wenn scope gleich "agent" ist |
Der KI-Agent, dessen Konversationen getaggt werden sollen. Wenn scope gleich "contacts" ist, ist dies optional und schränkt lediglich ein, welche Tag-Regeln des Agenten ausgeführt werden. |
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"] }'
Ein einzelner Kontakt wird inline ausgeführt und liefert das Ergebnis sofort zurück:
{ "success": true, "result": { "tags_applied": 2, "tags_removed": 0 } }
Zwei oder mehr Kontakte (oder scope: "agent") werden als Hintergrundjob ausgeführt und geben sofort 202 zurück:
{ "success": true, "run_id": "m1x2y3-a1b2c3d4", "total": 214 }
Einen Durchlauf abfragen
GET /contacts/auto-tag/run
Gibt den aktuellen (oder letzten) Durchlauf des Kontos zurück, sodass Sie den Fortschritt abfragen können, ohne run_id selbst nachverfolgen zu müssen.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/auto-tag/run?apiKey=YOUR_API_KEY"
Antwort
{
"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 ist null, wenn das Konto noch nie einen Durchlauf gestartet hat. status wechselt von "running" zu "completed" oder "failed".
Pro Konto kann immer nur ein Massendurchlauf gleichzeitig aktiv sein – der Start eines zweiten Durchlaufs, während ein anderer läuft, gibt 409 mit error_code: "auto_tag_run_in_progress" zurück. Wenn bei einem Einzelkontakt-Durchlauf die Kredite ausgehen, wird 402 mit error_code: "insufficient_credits" zurückgegeben; ein Massendurchlauf stoppt stattdessen vorzeitig und meldet in run, wie weit er gekommen ist.
Einen Kontakt löschen
DELETE /contacts/{contactId}
Löscht einen Kontakt dauerhaft anhand seiner ID, zusammen mit seinem Nachrichtenverlauf. Dies kann nicht rückgängig gemacht werden. Um mehrere Kontakte in einem einzigen Aufruf zu löschen, verwenden Sie unten Kontakte löschen.
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"])
Antwort
{
"success": true
}
Eine Kontakt-ID, die in Ihrem Konto nicht existiert oder zu einem anderen Konto gehört, gibt einen 404 zurück.
Kontakte löschen
DELETE /contacts
Löscht dauerhaft einen oder mehrere Kontakte anhand ihrer ID in einem einzigen Aufruf (bis zu 500 IDs). IDs, die in Ihrem Konto nicht existieren, werden übersprungen und in skipped gezählt. Dies kann nicht rückgängig gemacht werden.
| Feld | Beschreibung |
|---|---|
contactIds |
Array der zu löschenden Kontakt-IDs (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']}")
Antwort
{
"success": true,
"deleted": 2,
"skipped": 0
}
Benutzerdefinierte Felder auflisten
GET /users/me/custom-fields — gibt die für Ihr Konto registrierten Schlüssel für benutzerdefinierte Felder zurück (diejenigen, die als Spalten und im Kontaktformular angezeigt werden), sodass eine Integration diese als Auswahlmöglichkeit anbieten kann, anstatt sie zu erraten.
curl "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/users/me/custom-fields?apiKey=YOUR_API_KEY"
Antwort (200)
{ "success": true, "custom_fields": ["tier", "company", "birthday"] }
Legen Sie die Liste mit PUT /users/me/custom-fields und derselben Array-Struktur fest.
Ein benutzerdefiniertes Feld löschen
DELETE /contacts/custom-fields/{fieldKey}
Entfernt einen benutzerdefinierten Feldschlüssel von jedem Kontakt in Ihrem Konto. Verwenden Sie dies, um nach dem Umbenennen oder Entfernen eines benutzerdefinierten Feldes aufzuräumen. Der Schlüssel darf nur Buchstaben, Zahlen, Unterstriche und Bindestriche enthalten. Gibt zurück, wie viele Kontakte aktualisiert wurden. Dies kann nicht rückgängig gemacht werden.
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")
Antwort
{
"success": true,
"updated": 42
}
Hinweis: Ein Feld-Schlüssel mit nicht unterstützten Zeichen gibt ein 400 zurück.
Benutzerdefinierte Feldtypen
Jedes benutzerdefinierte Feld in einem Konto hat einen Typ: text (Standard), number, date, select (ein Dropdown mit festen Optionen) oder boolean (ein Kontrollkästchen). Ein typisiertes Feld wird bei jedem Schreibvorgang validiert – beim Erstellen, Aktualisieren, Importieren, durch die Automatisierungs-Engine und die eigene Felderfassung der KI – und sein Wert wird in einer kanonischen Form gespeichert, sodass Filter und Automatisierungsbedingungen Werte vergleichbar machen:
| Typ | Gespeichert als | Akzeptiert bei Eingabe |
|---|---|---|
text |
Was auch immer Sie senden | Alles (unverändertes Verhalten) |
number |
Eine JSON-Zahl | 42, "42", "19,99" |
date |
"YYYY-MM-DD" |
2026-02-01, ein ISO-Datum/Uhrzeit (der Datumsteil wird beibehalten), 01/02/2026 (Tag zuerst oder Monat zuerst gemäß Datumsformat des Kontos; ein eindeutiger Wert wie 13/02/2026 gewinnt immer), February 1, 2026, 1 de febrero de 2026 |
select |
Eine der Optionen des Feldes, in der Schreibweise der Option | Jede Übereinstimmung einer Option (Groß-/Kleinschreibung wird ignoriert) |
boolean |
true / false |
true/false, yes/no, 1/0, si/no, ja/nein … |
Das Senden von null oder einer leeren Zeichenfolge löscht ein typisiertes Feld. Schlüssel, die nicht im Konto registriert sind, sowie text-Felder werden exakt so gespeichert, wie sie gesendet wurden.
Felddefinitionen lesen
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 ist die einfache Liste der Schlüssel (unverändert für ältere Clients); definitions enthält den Typ pro Schlüssel.
Felddefinitionen festlegen
PUT /users/me/custom-fields
Ersetzt die gesamte Liste. Jeder Eintrag ist entweder ein einfacher Schlüssel (behält den Typ bei, den das Feld bereits hat, text für ein neues Feld) oder ein Objekt mit key, type und, für select, options (1 bis 100 eindeutige Optionen, bis zu 64 Zeichen jeweils). Maximal 50 Felder; Schlüssel verwenden Kleinbuchstaben, Ziffern und Unterstriche und beginnen mit einem Buchstaben oder Unterstrich.
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" }
]
}'
Das Ändern des Typs eines Feldes schreibt bereits gespeicherte Werte bei Kontakten nicht um; sie werden erst beim nächsten Schreibvorgang validiert.
Validierungsfehler
Das Erstellen oder Aktualisieren eines Kontakts, dessen benutzerdefinierte Feldwerte nicht zu ihrem Typ passen, wird insgesamt mit einem 400 abgelehnt:
{
"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)." }
]
}
Bei einem Massenimport wird der Datensatz mit dem fehlerhaften Wert mit derselben Meldung als fehlgeschlagen gemeldet, während der Rest des Batches verarbeitet wird.
Listen
Listen gruppieren Kontakte. Eine Liste ist entweder statisch (Sie entscheiden, wer darauf steht) oder intelligent (die Mitgliedschaft wird anhand von Regeln berechnet und automatisch auf dem neuesten Stand gehalten – siehe Listen & Kontakte organisieren).
| Feld | Beschreibung |
|---|---|
name |
Erforderlich bei der Erstellung. Bis zu 100 Zeichen. |
status |
live (Standard) oder draft. Kleingeschrieben. |
contact_ids |
Array von Kontakt-IDs, die der Liste hinzugefügt werden sollen. Nur für statische Listen. |
type |
static (Standard) oder smart. |
smart_rules |
Das Regelwerk – erforderlich, wenn type auf smart gesetzt ist. Siehe unten. |
Eine Liste erstellen
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" } }
]
}
}'
Antwort
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 3, "removed": 0, "total": 3 }
}
Eine intelligente Liste wird inline in derselben Anfrage ausgewertet, sodass evaluation Ihnen genau anzeigt, wer letztendlich darauf gelandet ist. Bei einer statischen Liste ist evaluation null.
Eine Liste aktualisieren
PUT /lists/{listId}
Senden Sie nur die Felder, die Sie ändern. Das Ändern von smart_rules wertet die Liste sofort neu aus und gibt dasselbe evaluation-Objekt zurück.
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"] } ] } }'
Sie können eine Liste zwischen den beiden Typen umschalten:
- Statisch → intelligent: Senden Sie
{ "type": "smart", "smart_rules": { … } }. Die Regeln greifen sofort. - Intelligent → statisch: Senden Sie
{ "type": "static" }. Die Regeln werden verworfen und alle Kontakte, die sich auf der Liste befinden, bleiben dort.
Die Struktur von 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(jede Bedingung muss wahr sein) oderany(mindestens eine).conditions— 1 bis 20 Bedingungen, jede mit maximal 100 Werten, Zeichenfolgen bis zu 200 Zeichen.
field |
op |
value |
|---|---|---|
tags |
has_any, has_all, has_none |
Array von Tag-IDs |
lists |
in_any, not_in_any |
Array von Listen-IDs (nur statische Listen – eine intelligente Liste kann nicht aus einer anderen intelligenten Liste erstellt werden) |
channel |
is_any, is_none |
Array von Kanälen |
status |
is_any, is_none |
Array von Kontaktstatus |
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" } |
| gleiche Datumsfelder | before, after |
ISO-Datum ("2026-01-01", Vergleich als ganze Tage) oder vollständiges ISO-Datum/Uhrzeit ("2026-01-01T14:30:00Z", Vergleich auf den genauen Zeitpunkt) |
| gleiche Datumsfelder | is_set, not_set |
— |
has_interacted_with_ai |
is |
true / false – true entspricht Kontakten, denen die KI mindestens einmal (überhaupt) eine Nachricht gesendet hat |
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 |
Zeichenfolge für die contains-Formulare |
current_campaign_id, assigned_agent |
is_any, is_none, is_set, not_set |
Array von IDs für die is_any / is_none-Formulare |
custom_field (plus ein key) |
eq, neq, contains, not_contains, is_set, not_set |
Zeichenfolge für die Wert-Formulare |
not_within_last findet auch Kontakte, bei denen das Datum nie festgelegt wurde („vor mehr als N Tagen, oder nie“), und Textvergleiche ignorieren die Groß-/Kleinschreibung.
KI-Interaktion. has_interacted_with_ai ist das lebenslange Flag: true für jeden Kontakt, dem Ihre KI mindestens eine Nachricht gesendet hat, false für alle anderen (einschließlich Kontakte, auf die nur Ihr Team geantwortet hat). Es wird bei der ersten Nachricht der KI an einen Kontakt gesetzt und nie gelöscht. Das Deaktivieren der KI-Antworten für den Kontakt oder das Verschieben in eine andere Kampagne setzt es daher nicht zurück. Für einen Zeitraum – „die Kontakte, die meine KI diesen Monat bearbeitet hat“, die übliche Abrechnungsfrage – verwenden Sie stattdessen den Bereich last_ai_interaction_at:
{ "field": "last_ai_interaction_at", "op": "within_last", "value": { "amount": 30, "unit": "days" } }
Verwechseln Sie beides nicht mit is_bot_active (die KI darf antworten, nicht dass sie es getan hat) oder has_ever_responded (der Kontakt hat geantwortet, an wen auch immer). Dieselben zwei Zeitstempel werden bei jedem Kontakt als first_ai_interaction_at / last_ai_interaction_at zurückgegeben, und der gesamte Regelsatz funktioniert auch mit GET /contacts?rules=, sodass Sie Übereinstimmungen zählen können, ohne eine Liste zu erstellen.
Regelwerk in der Vorschau anzeigen
POST /lists/preview
Zählt und stichprobt die Kontakte, die ein Regelwerk erfassen würde, ohne etwas zu erstellen oder zu ändern. Verwenden Sie dies, um Regeln auf Plausibilität zu prüfen, bevor Sie sie speichern.
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"] } ] } }'
Antwort
{
"success": true,
"count": 3,
"sample": [
{
"id": "contact_abc123",
"first_name": "Sofia",
"last_name": "Martinez",
"phone_number": "+31600000000",
"email": "sofia@example.com",
"channel": "whatsapp"
}
]
}
sample enthält bis zu 10 Kontakte, sortiert nach der letzten Aktivität.
Smart List jetzt erneut ausführen
POST /lists/{listId}/evaluate
Erzwingt eine sofortige Neubewertung (dasselbe, was Jetzt aktualisieren im Dashboard bewirkt). Smart Lists werden bereits bei Kontaktänderungen sowie alle 15 Minuten bei zeitbasierten Regeln aktualisiert; dies ist also nur erforderlich, wenn Sie das Ergebnis sofort benötigen.
Antwort
{
"success": true,
"list_id": "list_abc123",
"evaluation": { "added": 2, "removed": 1, "total": 4 }
}
evaluation.skipped: true bedeutet, dass bereits eine Auswertung derselben Liste lief und dieser Aufruf keine Auswirkungen hatte.
Smart Lists akzeptieren keine manuell hinzugefügten Mitglieder
Mitgliedschafts-Endpunkte geben 409 mit "This is a smart list — its members are computed from its rules. Edit the rules instead." zurück, wenn die Ziel-Liste eine Smart List ist. Dies betrifft POST /contacts/lists, DELETE /contacts/lists, POST /contacts/lists/batch, contact_ids bei POST /lists und PUT /lists/{listId} sowie die Auswahl einer Smart List als Ziel für einen CSV-Import. Ändern Sie stattdessen die Regeln.
Der Aufruf von POST /lists/{listId}/evaluate für eine statische Liste ist ebenfalls ein 409 — sie hat keine Regeln, die ausgeführt werden könnten.
Kontakte-API-Fehler
Kontakt-Endpunkte geben das Standard-Fehler-Envelope zurück:
{
"success": false,
"error": "Contact not found"
}
Einige Endpunkte enthalten auch error_code, was normalerweise dem HTTP-Status entspricht — die einzige Ausnahme ist der unten beschriebene Fall eines doppelten Kontakts, bei dem der HTTP-Status 200 ist und nur error_code den 409 enthält. Die spezifischen Codes für Kontakt-Endpunkte:
| Code | Wann dies bei einem Kontakt-Endpunkt auftritt |
|---|---|
400 |
Ungültige Anfrage — ein fehlendes/ungültiges Feld, ein leerer Body, ein fehlerhafter Cursor oder mehr als 500 IDs in einem Batch. |
402 |
Nicht genügend Credits, um einen KI-Tagging-Durchlauf für einen Kontakt (error_code: "insufficient_credits") abzuschließen. |
404 |
Der Kontakt, die Liste oder das Tag wurde in Ihrem Konto nicht gefunden. |
409 |
Ein Kontakt mit dieser Telefonnummer existiert bereits (beim Erstellen). Wird als error_code im Body mit einem HTTP-Status von 200 zurückgegeben, daher hier nach error_code verzweigen. Wird auch zurückgegeben, wenn ein automatischer Bulk-Tagging-Durchlauf bereits läuft (error_code: "auto_tag_run_in_progress") oder wenn die Verknüpfung eines Kontakts mit einem anderen Kanal zwei Kontakte verbinden würde, die bereits mit zwei verschiedenen Personen verknüpft sind. |
422 |
Der Kontakt kann derzeit keine Nachricht empfangen (Nicht-stören-Modus, privat oder nicht unterstützter Kanal). Beim Kanal-Verknüpfungs-Endpunkt deckt dies auch fehlende Telefonnummern, eine nicht unterstützte Kanal-Kopplung oder keinen verbundenen Absender für den Zielkanal ab. |
Ein 403 bei einem Kontakt-Endpunkt kann auch ein Problem mit dem Kontaktlimit oder der Listenberechtigung bedeuten, anstatt ein Problem mit dem Tarifzugriff. Die gemeinsamen Codes, die jeder Endpunkt zurückgeben kann — 401, 403 (Ihr Tarif beinhaltet keinen API-Zugriff), 429 (Ratenbegrenzung) und 500 — sind mit Hinweisen zur Wiederholung unter Fehler & Paginierung aufgeführt.
Nächste Schritte
- Messages API — Nachrichten nach Kanalidentität senden und Konversationen verwalten.
- API-Referenz — vollständige Endpunktliste, einschließlich Tags und Listen.
- API-Zugriff — Authentifizierung, Ratenbegrenzungen und Fehlerbehandlung.