Your AI Connector Docs

API Contacte

Un contact este o persoană căreia îi trimiți mesaje — numele, numărul de telefon, adresa de e-mail, canalul, etichetele, câmpurile personalizate, precum și listele și campaniile din care face parte. API-ul de Contacte îți permite să creezi contacte, să le cauți, să le actualizezi, să le etichetezi, să le imporți în masă și să le elimini, totul fără a utiliza tabloul de bord.

Toate căile de pe această pagină sunt relative la URL-ul de bază:

https://api.youraiconnector.com/v1

Așadar, /contacts înseamnă https://api.youraiconnector.com/v1/contacts.

Ești nou în utilizarea API-ului? Citește mai întâi Acces API — acesta acoperă modul de generare a cheii API, cele trei metode de autentificare, limitele de rată și formatul erorilor. Tot ce este pe această pagină presupune că ai deja o cheie API funcțională.


Despre ID-urile de contact

Fiecare contact are un ID unic. ID-ul pe care îl primești atunci când creezi un contact (în data.contactId) este același ID pe care îl folosești peste tot în altă parte — pentru a prelua, actualiza, eticheta, trimite un mesaj sau șterge acel contact. Salvează-l o dată și refolosește-l.

Nu trebuie să creezi un contact pentru a-i obține ID-ul. De asemenea, îl poți căuta după numărul de telefon sau adresa de e-mail (vezi Obține un contact) sau poți parcurge toate contactele (vezi Listează contactele). Fiecare dintre acestea returnează același ID.


Creează un contact

POST /contacts

Adaugă un contact nou în contul tău. Este obligatoriu un număr de telefon cu prefix de țară — o adresă de e-mail nu este suficientă. Orice altceva este opțional.

Poți, opțional, să adaugi noul contact direct într-una sau mai multe liste folosind listId (o singură listă) sau listIds (o matrice). Dacă sunt trimise ambele, listIds are prioritate.

Orice câmp pe care îl trimiți și care nu este unul dintre câmpurile standard de creare enumerate în tabelul de câmpuri Creează un contact de mai jos (phoneNumber, firstName, lastName, email, channel, is_bot_active, is_private, lead_profile, listId, listIds, custom_fields) este stocat automat ca un câmp personalizat — astfel încât un payload plat de la un instrument precum Make sau Zapier funcționează fără imbricare. De asemenea, poți transmite un obiect custom_fields explicit.

Câmp Obligatoriu Descriere
phoneNumber Da Numărul de telefon al contactului, cu prefix de țară (de ex. +15551234567).
firstName Nu Prenume.
lastName Nu Nume de familie.
email Nu Adresă de e-mail.
channel Nu Canal de mesagerie. Unul dintre whatsapp, sms, whatsapp_web. Implicit este whatsapp.
is_bot_active Nu Dacă asistentul AI răspunde acestui contact. Implicit este true.
is_private Nu Marchează contactul ca privat. Când este true, asistentul AI este dezactivat pentru acesta. Implicit este false.
lead_profile Nu Note text libere despre lead.
listId Nu Un singur ID de listă în care să adaugi contactul.
listIds Nu O matrice de ID-uri de liste în care să adaugi contactul (are prioritate față de listId).
custom_fields Nu Un obiect cu propriile tale câmpuri cheie/valoare. Poți, de asemenea, să le transmiți ca chei de nivel superior.

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

Răspuns

{
  "success": true,
  "data": {
    "message": "Successfully created new contact",
    "contactId": "contact_abc123",
    "listsAdded": ["list123", "list456"]
  }
}

ID-ul noului contact se află la data.contactId. Listele în care a fost adăugat sunt returnate în data.listsAdded.

Nu se creează duplicate. Dacă un contact cu același număr de telefon există deja, apelul de creare nu îl creează și nici nu îl returnează. Răspunsul revine cu starea HTTP 200 și un error_code de 409 în corp, deci verifică error_code în loc de starea HTTP:

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

Pentru a lucra cu un contact existent după un error_code de 409, caută-l cu Obține un contact prin telefon sau e-mailGET /contacts?phoneNumber=... — și refolosește ID-ul pe care îl returnează.

Scrierile echivalente în WhatsApp sunt considerate același număr. Unele țări au două moduri valide de scriere pentru aceeași linie mobilă, iar WhatsApp poate raporta oricare dintre ele: Mexic (+52… și varianta veche +521…), Brazilia (cu sau fără a noua cifră) și Argentina (cu sau fără 9 după +54). Verificarea duplicatelor la creare și potrivirea GET /contacts?phoneNumber= funcționează pentru ambele moduri de scriere, astfel încât veți primi înapoi contactul existent indiferent de forma pe care o trimiteți. phone_number stocat în contact nu este niciodată suprascris.


Obține un contact prin telefon sau e-mail

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

Caută un singur contact și returnează obiectul complet și îmbogățit al contactului — incluzând listele, etichetele și campaniile sale rezolvate în perechi { id, name }, plus ultimul mesaj schimbat.

Transmite fie phoneNumber (în format internațional), fie email. Dacă nu transmiți niciunul, acest endpoint comută în schimb la modul Listare contacte.

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

Răspuns

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

ID-ul contactului este returnat atât la nivelul superior (contactId), cât și în interiorul obiectului (contact.id). Dacă nu există nicio potrivire, primești un 404 cu { "success": false, "message": "Contact not found" }.

avatarUrl este fotografia de profil a contactului, preluată din WhatsApp sau Meta atunci când vă trimite un mesaj. Este doar în citire: nu o puteți seta și este null pentru contactele care nu au o fotografie sau care vă contactează printr-un canal care nu partajează una. Tratați linkul ca fiind temporar în loc să îl stocați, deoarece unele dintre aceste linkuri către fotografii expiră și sunt reîmprospătate automat. (În punctul final al listei de mai jos, aceeași valoare este numită avatar_url.)

Numere de telefon în URL-uri. Un semn + dintr-un șir de interogare trebuie să fie codificat URL ca %2B, altfel este citit ca un spațiu. Exemplele de mai sus fac acest lucru pentru tine.


Obțineți un contact după ID

GET /contacts/{contactId}

Când aveți deja ID-ul unui contact, preluați-l direct. Structura răspunsului este identică cu cea a căutării de mai sus.

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

Un ID de contact care nu există în contul dvs. va returna un 404.


Obține statisticile contactului

GET /contacts/{contactId}/stats

Returnează statistici agregate ale mesajelor pentru un contact: totaluri, răspunsuri AI vs. umane, credite consumate și marcaje temporale pentru primul/ultimul mesaj.

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

Răspuns

{
  "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 este același contor de mesaje AI pe care butonul „reset” din aplicație îl resetează pentru un contact. creditsUsed este totalul curent de credite pentru acest contact, nu doar cifrele acestui răspuns. Un ID de contact care nu există în contul tău returnează un 404.


Listare contacte

GET /contacts

Apelați GET /contacts fără phoneNumber sau email pentru a parcurge toate contactele, începând cu cele mai noi. Fiecare pagină returnează rezumate compacte ale contactelor (listele, etichetele și campaniile sunt returnate ca matrice de ID-uri, nu ca obiecte complete) și un next_cursor.

Parametru de interogare Descriere
limit Dimensiunea paginii. Valoarea implicită este 50, maxim 100.
cursor Valoarea next_cursor din pagina anterioară. Omiteți-o pe prima pagină.
listId Opțional. Returnează doar contactele care aparțin acestei liste.

Pentru a parcurge fiecare pagină: efectuați primul apel fără cursor, apoi continuați să transmiteți next_cursor returnat ca cursor. Opriți-vă când next_cursor este null — acest lucru înseamnă că nu mai există rezultate.

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

Răspuns

{
  "success": true,
  "contacts": [
    {
      "id": "contact_abc123",
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane@example.com",
      "phone_number": "+15551234567",
      "channel": "whatsapp",
      "is_bot_active": true,
      "is_private": false,
      "do_not_disturb": false,
      "avatar_url": "https://example.com/photo.jpg",
      "custom_fields": {},
      "created_at": "2026-06-01T09:00:00.000Z",
      "list_ids": ["list123"],
      "tag_ids": ["tagHotLead"],
      "campaign_ids": ["campaign789"],
      "current_campaign_id": "campaign789"
    }
  ],
  "next_cursor": "contact_abc123"
}

Notă: Filtrarea după un listId care nu există în contul tău returnează un 404. Un cursor nevalid returnează un 400.


Numărarea contactelor

GET /contacts/count

Returnează numărul de contacte care corespund unui filtru, plus o defalcare pe canal, fără a fi nevoie de paginare. Acesta este apelul potrivit pentru orice întrebare de tipul „câte sunt” — pentru un element de tablou de bord, o automatizare sau pentru a întreba Champ. Toate filtrele sunt opționale, iar combinarea mai multora restrânge numărătoarea (un contact trebuie să corespundă fiecăruia dintre ele).

Parametru de interogare Descriere
agentId Doar contactele alocate acestui agent AI. Trimiteți none pentru contactele fără un agent alocat (cele care sunt gestionate de agentul implicit al canalului).
channel Doar contactele de pe acest canal, de ex. whatsapp, messenger, instagram, sms, email, chat_widget.
tag Doar contactele care poartă această etichetă, după numele etichetei (majusculele/minusculele nu contează). Un nume de etichetă pe care nu îl aveți returnează 404.
listId Doar contactele din această listă.
botActive true sau false — doar contactele al căror asistent AI este activat sau dezactivat.
status Doar contactele cu acest status, de ex. Lead.
rules Un obiect JSON de reguli codificat URL, folosind aceeași formă ca o listă inteligentă (consultați Forma smart_rules mai jos). Nu poate fi combinat cu celelalte filtre.

Dacă nu trimiteți niciun filtru, veți primi numărul total de contacte din contul dumneavoastră.

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

Răspuns

{
  "success": true,
  "total": 3423,
  "by_channel": { "messenger": 2744, "instagram": 667, "none": 12 },
  "filters": { "agentId": "agent_xyz789" }
}

by_channel împarte același total pe canal; contactele care nu sunt pe niciun canal sunt numărate sub none. filters returnează filtrele care au fost aplicate, astfel încât să puteți verifica dacă apelul a făcut ceea ce ați dorit.

Notă: Trimiterea rules împreună cu orice alt filtru sau o valoare rules care nu este un JSON valid returnează 400. Un nume de etichetă sau un ID de listă care nu există în contul dumneavoastră returnează 404.


Actualizarea unui contact

PUT /contacts/{contactId}

Actualizează un contact existent. Doar câmpurile pe care le incluzi sunt modificate — omite tot ce nu dorești să atingi. Trebuie să trimiți cel puțin un câmp, altfel vei primi un 400 („Nu există câmpuri de actualizat”).

Câmp Descriere
firstName Prenume.
lastName Nume de familie.
email Adresă de e-mail.
is_bot_active Dacă asistentul AI răspunde acestui contact.
is_private Marchează ca privat. Setarea acestei opțiuni pe true dezactivează, de asemenea, asistentul AI.
do_not_disturb Întrerupe comunicarea automată cu acest contact. De asemenea, oprește AI-ul din a răspunde.
follow_ups_disabled Oprește toate mesajele de follow-up automate pentru acest contact (rapide, ciclice și pentru lead-uri reci) în timp ce AI-ul continuă să răspundă la mesajele trimise de acesta. Util după ce cineva a efectuat o achiziție. Rămâne dezactivat până când îl setați înapoi la false.
lead_profile Note despre lead sub formă de text liber.
custom_fields Un obiect de câmpuri personalizate. Îmbinate per cheie — sunt scrise doar cheile pe care le trimiteți, restul câmpurilor personalizate existente sunt păstrate. Puteți, de asemenea, să transmiteți chei de câmpuri personalizate la nivelul superior.

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

Răspuns

{
  "success": true,
  "message": "Contact updated successfully"
}

Câmpurile personalizate sunt îmbinate, nu înlocuite. Trimiterea { "custom_fields": { "tier": "gold" } } setează doar tier — orice alte câmpuri personalizate de pe contact rămân exact așa cum erau. Pentru a elimina complet un câmp personalizat din toate contactele, folosește Ștergerea unui câmp personalizat.


Adăugarea sau eliminarea etichetelor

POST /contacts/{contactId}/tags

Adaugă și/sau elimină etichete de pe un singur contact într-un singur apel. Transmite ID-urile etichetelor în addTagIds și removeTagIds. Cel puțin unul dintre cele două trebuie să fie nevid.

Etichetele trebuie să existe deja în contul tău — creează-le mai întâi prin endpoint-ul de etichete. Dacă contactul sau oricare dintre etichetele referențiate nu există, vei primi un 404.

Câmp Descriere
addTagIds Matrice de ID-uri de etichete de adăugat la contact.
removeTagIds Matrice de ID-uri de etichete de eliminat din contact.

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

Răspuns

{
  "success": true,
  "contact_id": "contact_abc123",
  "added": 1,
  "removed": 1
}

Gestionează biblioteca de etichete

Aceste endpoint-uri gestionează eticheta în sine — redenumirea sau ștergerea acesteia din contul tău — spre deosebire de aplicarea sau eliminarea unei etichete de pe un contact (vezi Adăugarea sau eliminarea etichetelor mai sus). Fiecare etichetă din contul tău are un ID (tagId): cel afișat în managerul de etichete din tabloul de bord și cel returnat ca data.tag_id atunci când creezi o etichetă cu POST /tags și un corp JSON de { "name": "..." } (fără phoneNumber, email sau contactId).

Actualizarea unei etichete

PUT /tags/{tagId}

Trimite doar câmpurile pe care le modifici.

Câmp Descriere
name Numele etichetei.
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)" }'

Răspuns

{ "success": true, "tag_id": "tagHotLead" }

Un tagId care nu există în contul tău returnează un 404.

Ștergerea unei etichete

DELETE /tags/{tagId}

Șterge o etichetă după ID. Această acțiune nu poate fi anulată — contactele care poartă eticheta o vor pierde pur și simplu. Ștergerea unei etichete care a fost deja eliminată (sau care nu a existat niciodată) returnează 200 cu deleted: 0 în loc de 404, deoarece nu există nimic de enumerat.

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

Răspuns

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

Ștergerea mai multor etichete simultan

DELETE /tags

Câmp Descriere
tagIds Matrice de ID-uri de etichete de șters (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"] }'

Răspuns

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

ID-urile care nu există sau aparțin altui cont sunt omise silențios și nu sunt numărate în deleted.


Setare în masă a unui indicator

POST /contacts/bulk-flag

Setează un indicator boolean pentru mai multe contacte simultan. Până la 500 de ID-uri de contact per cerere. ID-urile care nu există în contul tău sunt omise și numărate în skipped.

Câmp Descriere
contactIds Matrice de ID-uri de contact de actualizat (max 500).
field Ce indicator să setezi. Unul dintre bot_active (asistent AI pornit/oprit), dnd (întrerupere comunicare automată), spam, private.
value Valoarea booleană la care să setezi indicatorul.

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

Răspuns

{
  "success": true,
  "updated": 2,
  "skipped": 0
}

Import în masă al contactelor

POST /contacts/import

Creează până la 500 de contacte într-un singur apel dintr-o matrice JSON. Fiecare înregistrare necesită un phone_number în format internațional; tot restul este opțional. Înregistrările cu numere de telefon invalide sau canale neacceptate sunt omise (nu sunt create), iar fiecare înregistrare omisă este raportată cu indicele și motivul său — astfel încât să puteți corecta doar eșecurile și să reîncercați.

Numerele de telefon care există deja în contul dvs. sunt omise implicit ca duplicate. Trimiteți updateExisting: true pentru a actualiza acele contacte în schimb: câmpurile prezente în înregistrare suprascriu datele contactului (first_name, last_name, email, lead_profile și custom_fields sunt îmbinate cheie cu cheie), tags sunt adăugate, iar contactul este adăugat la listId. Canalul, numărul de telefon și indicatorii botului nu sunt niciodată modificați pentru un contact existent.

Puteți adăuga opțional fiecare contact importat (sau actualizat) la o listă cu listId, seta un defaultChannel pentru înregistrările care nu specifică unul și eticheta înregistrările cu tags (numele etichetelor — etichetele lipsă sunt create, cele existente sunt potrivite indiferent de majuscule/minuscule).

Câmpuri de nivel superior

Câmp Obligatoriu Descriere
contacts Da Matrice de înregistrări de contacte (max 500).
listId Nu Listă la care să fie adăugat fiecare contact importat (și actualizat). Trebuie să fie o listă din contul dvs.
defaultChannel Nu Canal aplicat înregistrărilor care omit channel. Unul dintre whatsapp, sms, whatsapp_web. Implicit este whatsapp.
updateExisting Nu true pentru a actualiza contactele al căror număr de telefon există deja, în loc să le omiteți ca duplicate. Implicit este false.

Câmpuri per înregistrare

Câmp Obligatoriu Descriere
phone_number Da Număr de telefon în format internațional (un + inițial este adăugat dacă lipsește).
first_name Nu Prenume.
last_name Nu Nume de familie.
email Nu Adresă de e-mail.
channel Nu Unul dintre whatsapp, sms, whatsapp_web. Revine la defaultChannel.
is_bot_active Nu Dacă asistentul AI răspunde. Implicit este true.
is_private Nu Marchează ca privat. Implicit este false.
lead_profile Nu Note despre lead în text liber.
custom_fields Nu Obiect de chei și valori pentru câmpuri personalizate.
tags Nu Matrice de nume de etichete (funcționează și un singur șir "a; b"). Etichetele care nu există sunt create; cele existente sunt potrivite ignorând majusculele/minusculele. Max 25 per înregistrare.

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

Răspuns

{
  "success": true,
  "imported": 2,
  "contact_ids": ["contact_abc123", "contact_def456"],
  "updated": 0,
  "updated_contact_ids": [],
  "skipped": []
}

Dacă unele înregistrări nu pot fi create, acestea apar în skipped cu motivul (aici fără updateExisting, deci numărul existent este omis):

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

Cu updateExisting: true, aceeași cerere raportează contactul existent sub updated / updated_contact_ids în schimb.

Motive posibile pentru omitere: invalid_record, missing_phone_number, invalid_phone_number, invalid_channel, duplicate_in_request, duplicate, contact_limit_reached, create_failed.

Limite de plan. Dacă limita de contacte a planului dvs. nu permite un număr atât de mare de contacte noi, întreaga solicitare este respinsă din start cu un 403. Dacă limita este atinsă pe parcurs, înregistrările rămase sunt returnate ca omise cu motivul contact_limit_reached.


Importă contacte dintr-un fișier CSV

Pentru importuri mai mari decât cele suportate de importul în masă (până la aproximativ 50.000 de rânduri), puneți la coadă o sarcină de import asincron pentru un fișier CSV deja existent în stocarea contului dvs., apoi interogați-l până la finalizare.

Începe importul

POST /contacts/import-csv

Câmp Obligatoriu Descriere
csvStoragePath Da Calea de stocare a fișierului CSV, sub users/{your account id}/imports/, terminându-se în .csv.
listName Da Creează (sau reutilizează) o listă cu acest nume și adaugă fiecare contact importat în ea.
existingListRefs Nu Matrice de ID-uri de liste existente în care să fie adăugat, de asemenea, fiecare contact importat.
defaultChannel Nu Canal aplicat rândurilor care nu specifică unul.
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"]

Răspuns (202 — importul este pus la coadă, nu este încă finalizat)

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

Introducerea fișierului în stocare. Acest endpoint pornește și urmărește sarcina de import; nu acceptă el însuși o încărcare. Fișierul CSV trebuie să fie deja la csvStoragePath înainte de a-l apela — propriul importator CSV al tabloului de bord face acest lucru ca prim pas.

Interoghează jobul de import

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"

Răspuns

{
  "success": true,
  "job_id": "csvimp_abc123",
  "status": "completed",
  "imported": 812,
  "updated": 0,
  "skipped": 14,
  "errors": [],
  "error_message": null
}

status trece prin queuedprocessingcompleted sau failed cu motivul în error_message. Un jobId care nu există în contul dvs. returnează un 404.


Exportă contacte

Inițiază un export CSV asincron al contactelor dvs. și returnează o sarcină pe care o puteți interoga pentru finalizare.

Începe exportul

POST /contacts/export

Câmp Obligatoriu Descriere
listId Nu Exportă doar contactele care aparțin acestei liste.
contactIds Nu Exportă doar aceste ID-uri de contact specifice.

Dacă le lași pe ambele necompletate, se vor exporta toate contactele din contul tău.

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

Răspuns (202 — exportul este pus în coadă)

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

Interoghează starea exportului

GET /contacts/export/{jobId}

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

Răspuns

{
  "success": true,
  "job_id": "export_abc123",
  "status": "completed",
  "export_id": "exp_xyz789",
  "contact_count": 812,
  "error_message": null
}

Odată ce status este "completed", vei primi export_id și contact_count. Descărcarea fișierului CSV generat se face din pagina Exporturi a tabloului tău de bord.


Trimite un mesaj către un contact

POST /contacts/{contactId}/send-message

Trimite un mesaj unui contact existent pe canalul pe care acesta se află deja. Mesajul este pus în coadă și livrat în fundal — răspunsul confirmă că a fost acceptat, nu că a fost deja livrat.

Câmp Obligatoriu Descriere
body Da Textul mesajului de trimis.
mediaUrl Nu URL-ul unui fișier media de atașat.
mediaContentType Nu Tipul MIME al fișierului media atașat (de ex. image/jpeg).

cURL

curl -X POST "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "body": "Hi! Your appointment is confirmed." }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ body: "Hi! Your appointment is confirmed." }),
});
const data = await res.json();
console.log(data.messageId);

Python

import requests

res = requests.post(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts/contact_abc123/send-message",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"body": "Hi! Your appointment is confirmed."},
)
print(res.json()["messageId"])

Răspuns

{
  "success": true,
  "messageId": "aB3dE5fG7hI9jK1lM2nO",
  "contactId": "contact_abc123",
  "channel": "whatsapp",
  "message": "Message created successfully. Delivery is being processed."
}

Nu poți trimite acum? Dacă persoana de contact are activat modul „nu deranja” sau modul privat, ori nu se află pe un canal care poate primi mesaje de ieșire, cererea este respinsă cu un 422 și un error explicativ.

Pentru trimiterea prin număr de telefon, ID de Instagram sau altă identitate de canal în loc de un ID de contact — și pentru mai multe informații despre mesagerie în general — consultă Messages API.


Atribuie un agent AI unui contact

POST /contacts/{contactId}/assign-agent

Mută o conversație existentă către un alt agent AI, începând cu următorul mesaj. Este același lucru cu Atribuire agent AI din meniul unui chat și este aceeași acțiune pe care o folosește pasul Atribuie agent AI sau campanie în Automatizări.

Câmp Obligatoriu Descriere
agentId Da ID-ul agentului AI care ar trebui să preia conversația sau null pentru a șterge atribuirea, astfel încât conversația să revină în inbox-ul echipei tale.
triggerAIResponse Nu true determină noul agent atribuit să răspundă imediat la ultimele mesaje fără răspuns ale contactului. Valoarea implicită este false.

Atenție la triggerAIResponse: true — acesta trimite contactului un mesaj pe loc, așa că folosiți-l doar atunci când doriți ca acesta să primească mesajul imediat. Pe Messenger și Instagram, acel mesaj eșuează dacă contactul v-a scris ultima dată acum mai mult de 24 de ore.

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

Răspuns

{
  "success": true,
  "data": {
    "contactId": "contact_abc123",
    "agentId": "agent_xyz789",
    "aiResponseTriggered": false
  }
}

Agentul trebuie să aparțină aceluiași cont ca și contactul; în caz contrar, cererea este respinsă cu o eroare 404 sau 403. Găsește ID-urile agenților pe pagina Agenți AI (URL-ul fiecărui agent se termină cu ID-ul său).


Alocarea unui agent AI către mai multe contacte

POST /contacts/bulk-assign-agent

Mută mai multe conversații către un alt agent AI într-un singur apel — sau șterge alocarea pentru toate acestea cu null. Este pur și simplu o modificare de rutare: nu se trimite niciun mesaj și agentul nu răspunde nimănui. Fiecare contact primește pur și simplu noul agent data viitoare când scrie. (De aceea nu există triggerAIResponse aici.)

Câmp Obligatoriu Descriere
agentId Da Agentul AI care ar trebui să preia sarcina sau null pentru a șterge alocarea.
contactIds Unul dintre cele trei Până la 500 de ID-uri de contact de mutat.
filter Unul dintre cele trei Selectați contactele de pe server în loc să le listați, cele mai noi primele. Utilizează aceleași chei ca filtrele endpoint-ului de numărare: agentId (sau none), channel, tag, listId, botActive, status.
rules Unul dintre cele trei Un obiect de reguli pentru listă inteligentă — consultați Forma smart_rules.
limit Nu Câte contacte să mutați în acest apel când selectați cu filter sau rules. De la 1 la 500, implicit 500.

Trimiteți exact unul dintre contactIds, filter sau 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"])

Răspuns

{
  "success": true,
  "agentId": "agent_xyz789",
  "matched": 3415,
  "updated": 500,
  "skipped": 0,
  "remaining": 2915,
  "filters": { "agentId": "agent_abc123" }
}

matched reprezintă câte contacte a găsit selecția în total, updated câte au fost mutate prin acest apel, skipped câte dintre ID-urile trimise nu au fost găsite în contul dumneavoastră și remaining câte mai corespund acum după finalizarea apelului.

Mutarea tuturor. Deoarece un apel mută cel mult 500 de contacte, un grup mare necesită câteva apeluri. Folosiți un filtru care încetează să mai corespundă unui contact odată ce acesta a fost mutat — de exemplu filter: { "agentId": "agent_abc123" } în timp ce alocați către agent_xyz789 — și repetați exact același apel până când remaining revine ca 0. Când trimiteți contactIds în schimb, remaining este întotdeauna 0.


Alocă un contact unui departament

POST /contacts/{contactId}/department

„Alocă acest lead către Vânzări” — înregistrează un contact sub un departament numit și, în mod implicit, îl atribuie persoanei din acel departament care are în prezent cele mai puține contacte. Aceasta este o acțiune separată de alocarea unui agent AI: un departament răspunde la întrebarea „ce echipă deține acest lucru”, un agent răspunde la „ce AI răspunde la acest lucru”, iar setarea uneia nu o șterge niciodată pe cealaltă.

Câmp Obligatoriu Descriere
department_id Da Departamentul sub care se înregistrează contactul. Trimite null pentru a-l șterge.
hand_to_member Nu De asemenea, atribuie contactul persoanei cu cea mai mică încărcare din acel departament. Valoarea implicită este true. Nu realocă niciodată un contact pe care cineva îl deține deja.

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

Răspuns

{
  "success": true,
  "department_id": "dept_sales",
  "assigned_to": "member_uid_123"
}

assigned_to este null atunci când contactul era deja deținut de cineva sau ai trimis hand_to_member: false.


Conectează un contact prin mai multe canale

„Continuă pe WhatsApp” (sau SMS) găsește sau creează contactul acestei persoane pe un alt canal bazat pe telefon și le leagă între ele, astfel încât restul aplicației să le recunoască drept aceeași persoană.

Conectarea la un alt canal

POST /contacts/{contactId}/link-channel

Câmp Obligatoriu Descriere
channel Da Canalul la care se face conectarea. Unul dintre whatsapp, whatsapp_web, sms.
phoneNumber Nu Numărul de telefon de utilizat pe noul canal. Implicit este numărul propriu al contactului sursă.
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" }'

Răspuns

{
  "success": true,
  "data": {
    "contact_id": "contact_def456",
    "person_id": "person_xyz789",
    "created": true
  }
}

created vă indică dacă un contact nou a fost creat pentru canalul țintă sau dacă a fost găsit și conectat unul existent. Apelarea acestei funcții a doua oară este sigură — returnează același contact_id cu created: false în loc să creeze un duplicat.

O eroare 422 înseamnă că contul nu poate efectua această conectare în acest moment: contactul se află deja în acea familie de canale, nu are un număr de telefon de utilizat sau nu există niciun expeditor conectat pentru canalul țintă. O eroare 409 înseamnă că cele două contacte sunt deja conectate la două persoane diferite — deconectați-l pe unul mai întâi.

Listarea conversațiilor conectate ale unui contact

GET /contacts/{contactId}/linked

Returnează celelalte conversații care reprezintă aceeași persoană ca acest contact. Un contact neconectat returnează o matrice goală, nu o eroare 404 — „această persoană nu are alte canale” este o stare normală.

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

Răspuns

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

Deconectarea unui contact

DELETE /contacts/{contactId}/link

Elimină acest contact din persoana sa, unilateral — orice alte contacte încă legate de acea persoană își păstrează conexiunea, deci deconectarea unuia din trei nu dizolvă grupul.

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

Răspuns

{ "success": true }

Preluarea fotografiei de profil a unui contact

POST /contacts/{contactId}/profile-pic

Preluarea (și stocarea în cache) fotografiei de profil WhatsApp sau Meta a contactului la cerere — aceeași fotografie returnată ca avatarUrl în Obținere contact, actualizată.

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

Răspuns

{
  "success": true,
  "avatar_url": "https://example.com/photo.jpg",
  "cached": false
}

cached: true înseamnă că URL-ul provine dintr-o preluare recentă, nu dintr-o căutare proaspătă la furnizor — fotografiile sunt stocate în cache timp de 7 zile, iar un contact despre care furnizorul raportează că nu are nicio fotografie accesibilă este stocat ca indisponibil timp de 24 de ore. Când nu există nicio fotografie de preluat, avatar_url este omis și message explică motivul.


Etichetarea automată a contactelor cu AI

Rulează regulile de etichetare ale contului tău peste istoricul complet al conversațiilor unuia sau mai multor contacte și aplică (sau elimină) etichete exact ca etichetarea în timp real care rulează în timpul unui chat live — aceleași reguli, același cost de credite per etichetă.

Începe o rulare

POST /contacts/auto-tag

Câmp Obligatoriu Descriere
scope Da "contacts" pentru a eticheta contacte specifice sau "agent" pentru a eticheta fiecare conversație gestionată în prezent de un agent AI.
contact_ids Obligatoriu când scope este "contacts" Matrice de ID-uri de contact, de la 1 la 500.
agent_id Obligatoriu când scope este "agent" Agentul AI ale cărui conversații trebuie etichetate. Când scope este "contacts", acesta este opțional și doar restrânge regulile de etichetare ale agentului care rulează.
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"] }'

Un singur contact rulează inline și returnează rezultatul imediat:

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

Două sau mai multe contacte (sau scope: "agent") rulează ca un job de fundal și returnează 202 imediat:

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

Interoghează o rulare

GET /contacts/auto-tag/run

Returnează rularea curentă (sau cea mai recentă) a contului, astfel încât să poți interoga progresul fără a urmări singur run_id.

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

Răspuns

{
  "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 este null atunci când contul nu a început niciodată una. status trece de la "running" la "completed" sau "failed".

Doar o singură rulare în masă poate fi în curs per cont la un moment dat — pornirea unei a doua în timp ce alta rulează returnează 409 cu error_code: "auto_tag_run_in_progress". Epuizarea creditelor în timpul unei rulări pentru un singur contact returnează 402 cu error_code: "insufficient_credits"; o rulare în masă se oprește în schimb mai devreme și raportează cât de departe a ajuns în run.


Șterge un contact

DELETE /contacts/{contactId}

Șterge permanent un contact după ID, împreună cu istoricul mesajelor sale. Această acțiune nu poate fi anulată. Pentru a șterge mai multe contacte într-un singur apel, folosește Șterge contacte mai jos.

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

Răspuns

{
  "success": true
}

Un ID de contact care nu există în contul tău sau care aparține unui alt cont va returna o eroare 404.


Ștergerea contactelor

DELETE /contacts

Șterge definitiv unul sau mai multe contacte după ID într-un singur apel (până la 500 de ID-uri). ID-urile care nu există în contul tău sunt omise și numărate în skipped. Această acțiune nu poate fi anulată.

Câmp Descriere
contactIds Matrice de ID-uri de contact de șters (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']}")

Răspuns

{
  "success": true,
  "deleted": 2,
  "skipped": 0
}

Șterge un câmp personalizat

DELETE /contacts/custom-fields/{fieldKey}

Elimină o cheie de câmp personalizat din fiecare contact din contul tău. Folosește această opțiune pentru a face curățenie după redenumirea sau eliminarea unui câmp personalizat. Cheia poate conține doar litere, cifre, caractere de subliniere și cratime. Returnează numărul de contacte actualizate. Această acțiune nu poate fi anulată.

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

Răspuns

{
  "success": true,
  "updated": 42
}

Notă: O cheie de câmp cu caractere neacceptate returnează un 400.


Liste

Listele grupează contacte. O listă este fie statică (tu decizi cine face parte din ea), fie inteligentă (apartenența este calculată pe baza unor reguli și menținută la zi automat — vezi Organizarea listelor și a contactelor).

Câmp Descriere
name Obligatoriu la creare. Până la 100 de caractere.
status live (implicit) sau draft. Cu litere mici.
contact_ids Matrice de ID-uri de contacte de adăugat în listă. Doar pentru liste statice.
type static (implicit) sau smart.
smart_rules Setul de reguli — obligatoriu când type este smart. Vezi mai jos.

Crearea unei 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" } }
          ]
        }
      }'

Răspuns

{
  "success": true,
  "list_id": "list_abc123",
  "evaluation": { "added": 3, "removed": 0, "total": 3 }
}

O listă inteligentă este evaluată inline, în aceeași cerere, deci evaluation îți spune exact cine a ajuns în ea. În cazul unei liste statice, evaluation este null.

Actualizarea unei liste

PUT /lists/{listId}

Trimite doar câmpurile pe care le modifici. Modificarea smart_rules reevaluează lista imediat și returnează același obiect evaluation.

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

Poți schimba tipul unei liste între cele două variante:

  • Statică → inteligentă: trimite { "type": "smart", "smart_rules": { … } }. Regulile preiau controlul pe loc.
  • Inteligentă → statică: trimite { "type": "static" }. Regulile sunt eliminate, iar cei care se află deja în listă rămân acolo.

Structura 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" }
  ]
}
  • matchall (toate condițiile trebuie să fie adevărate) sau any (cel puțin una).
  • conditions — între 1 și 20 de condiții, fiecare cu cel mult 100 de valori, șiruri de caractere de până la 200 de caractere.
field op value
tags has_any, has_all, has_none matrice de ID-uri de etichete
lists in_any, not_in_any matrice de ID-uri de liste (doar liste statice — o listă inteligentă nu poate fi creată dintr-o altă listă inteligentă)
channel is_any, is_none matrice de canale
status is_any, is_none matrice de stări ale contactelor
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" }
aceleași câmpuri de dată before, after dată ISO ("2026-01-01", comparată ca zile întregi) sau dată-oră ISO completă ("2026-01-01T14:30:00Z", comparată cu momentul exact)
aceleași câmpuri de dată is_set, not_set
has_interacted_with_ai is true / falsetrue potrivește contactele cărora AI-ul le-a trimis cel puțin un mesaj (vreodată)
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 șir pentru formularele contains
current_campaign_id, assigned_agent is_any, is_none, is_set, not_set matrice de ID-uri pentru formularele is_any / is_none
custom_field (plus un key) eq, neq, contains, not_contains, is_set, not_set șir pentru formularele de valoare

not_within_last potrivește, de asemenea, contactele pentru care data nu a fost setată niciodată (“mai mult de N în urmă, sau niciodată”), iar comparațiile de text ignoră diferența dintre literele mari și mici.

Interacțiunea AI. has_interacted_with_ai este indicatorul pe întreaga durată de viață: true pentru fiecare contact căruia AI-ul tău i-a trimis cel puțin un mesaj, false pentru toți ceilalți (inclusiv contactele la care a răspuns doar echipa ta). Acesta este marcat la primul mesaj al AI-ului către un contact și nu este șters niciodată, deci dezactivarea răspunsurilor AI pentru contact sau mutarea acestuia într-o altă campanie nu îl resetează. Pentru o perioadă — „contactele gestionate de AI-ul meu luna aceasta”, întrebarea obișnuită de facturare — folosește intervalul last_ai_interaction_at:

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

Nu le confunda cu is_bot_active (AI-ul are permisiunea de a răspunde, nu înseamnă că a făcut-o) sau has_ever_responded (contactul a scris înapoi, oricui). Aceleași două marcaje sunt returnate pentru fiecare contact ca first_ai_interaction_at / last_ai_interaction_at, iar întregul set de reguli funcționează și pe GET /contacts?rules=, astfel încât poți număra potrivirile fără a crea o listă.

Previzualizarea unui set de reguli

POST /lists/preview

Numără și eșantionează contactele pe care un set de reguli le-ar potrivi, fără a crea sau a modifica nimic. Folosiți această funcție pentru a verifica validitatea regulilor înainte de a le salva.

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

Răspuns

{
  "success": true,
  "count": 3,
  "sample": [
    {
      "id": "contact_abc123",
      "first_name": "Sofia",
      "last_name": "Martinez",
      "phone_number": "+31600000000",
      "email": "sofia@example.com",
      "channel": "whatsapp"
    }
  ]
}

sample reține până la 10 contacte, sortate descrescător după activitatea recentă.

Rularea imediată a unei liste inteligente

POST /lists/{listId}/evaluate

Forțează o reevaluare imediată (același lucru pe care îl face Reîmprospătare acum în tabloul de bord). Listele inteligente se actualizează deja atunci când un contact se modifică și la fiecare 15 minute pentru regulile bazate pe timp, deci acest lucru este necesar doar atunci când doriți rezultatul chiar acum.

Răspuns

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

evaluation.skipped: true înseamnă că o altă evaluare a aceleiași liste era deja în curs de desfășurare și acest apel nu a produs niciun efect.

Listele inteligente refuză membrii selectați manual

Endpoint-urile de apartenență returnează 409 cu "This is a smart list — its members are computed from its rules. Edit the rules instead." atunci când lista țintă este inteligentă. Aceasta acoperă POST /contacts/lists, DELETE /contacts/lists, POST /contacts/lists/batch, contact_ids pe POST /lists și PUT /lists/{listId}, precum și alegerea unei liste inteligente ca țintă pentru importul CSV. Modificați regulile în schimb.

Apelarea POST /lists/{listId}/evaluate pe o listă statică este, de asemenea, o 409 — aceasta nu are reguli de rulat.


Erori API Contacte

Endpoint-urile pentru contacte returnează plicul standard de eroare:

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

Unele endpoint-uri includ, de asemenea, error_code, care de obicei corespunde stării HTTP — singura excepție este cazul contactului duplicat de mai jos, unde starea HTTP este 200 și doar error_code poartă 409. Codurile specifice endpoint-urilor de contact:

Cod Când apare pe un endpoint de contact
400 Cerere incorectă — un câmp lipsă/invalid, corp gol, cursor greșit sau peste 500 de ID-uri într-un lot.
402 Credite insuficiente pentru a finaliza o rulare de etichetare AI pe un contact (error_code: "insufficient_credits").
404 Contactul, lista sau eticheta nu a fost găsită în contul tău.
409 Un contact cu acel număr de telefon există deja (la creare). Returnat ca error_code în corp cu un status HTTP de 200, deci ramifică pe error_code aici. De asemenea, returnat când o rulare de etichetare automată în masă este deja în desfășurare (error_code: "auto_tag_run_in_progress") sau când legarea unui contact la un alt canal ar uni două contacte deja legate la două persoane diferite.
422 Contactul nu poate primi un mesaj în acest moment (nu deranja, privat sau canal neacceptat). Pe endpoint-ul de legătură a canalului, acoperă de asemenea lipsa numărului de telefon, o asociere de canal neacceptată sau lipsa unui expeditor conectat pentru canalul țintă.

Un 403 pe un endpoint de contact poate însemna, de asemenea, o problemă de limită de contacte sau de permisiune a listei, mai degrabă decât accesul la plan. Codurile partajate pe care orice endpoint le poate returna — 401, 403 (planul tău nu include acces API), 429 (limită de rată) și 500 — sunt enumerate cu instrucțiuni de reîncercare în Erori și Paginare.


Pașii următori

  • API Mesaje — trimite mesaje prin identitatea canalului și gestionează conversațiile.
  • Referință API — listă completă de endpoint-uri, inclusiv etichete și liste.
  • Acces API — autentificare, limite de rată și gestionarea erorilor.