Your AI Connector Docs

API Kontak

Kontak adalah satu orang yang Anda kirimi pesan — nama, nomor telepon, email, saluran, tag, kolom kustom, serta daftar dan kampanye tempat mereka berada. API Kontak memungkinkan Anda membuat kontak, mencarinya, memperbaruinya, memberi tag, mengimpornya secara massal, dan menghapusnya, semuanya tanpa menggunakan dasbor.

Semua jalur di halaman ini bersifat relatif terhadap URL dasar:

https://api.youraiconnector.com/v1

Jadi /contacts berarti https://api.youraiconnector.com/v1/contacts.

Baru menggunakan API? Baca Akses API terlebih dahulu — bagian ini mencakup cara membuat kunci API Anda, tiga cara untuk melakukan autentikasi, batas kecepatan, dan format kesalahan. Semua yang ada di halaman ini mengasumsikan Anda sudah memiliki kunci API yang berfungsi.


Tentang ID kontak

Setiap kontak memiliki ID unik. ID yang Anda dapatkan saat membuat kontak (di data.contactId) adalah ID yang sama yang Anda gunakan di tempat lain — untuk mengambil, memperbarui, memberi tag, mengirim pesan, atau menghapus kontak tersebut. Simpan sekali dan gunakan kembali.

Anda tidak perlu membuat kontak untuk mendapatkan ID-nya. Anda juga dapat mencarinya berdasarkan nomor telepon atau email (lihat Mendapatkan kontak), atau menelusuri semua kontak Anda (lihat Daftar kontak). Masing-masing metode tersebut mengembalikan ID yang sama.


Membuat kontak

POST /contacts

Menambahkan kontak baru ke akun Anda. Nomor telepon dengan kode negara wajib diisi — email saja tidak cukup. Semua kolom lainnya bersifat opsional.

Anda dapat secara opsional memasukkan kontak baru langsung ke dalam satu atau beberapa daftar dengan listId (satu daftar) atau listIds (sebuah array). Jika keduanya dikirim, listIds yang akan digunakan.

Setiap kolom yang Anda kirimkan yang bukan merupakan salah satu kolom pembuatan standar yang tercantum dalam tabel kolom Buat kontak di bawah (phoneNumber, firstName, lastName, email, channel, is_bot_active, is_private, lead_profile, listId, listIds, custom_fields) akan disimpan secara otomatis sebagai kolom kustom — sehingga payload datar dari alat seperti Make atau Zapier dapat berfungsi tanpa perlu melakukan nesting. Anda juga dapat meneruskan objek custom_fields secara eksplisit.

Kolom Wajib Deskripsi
phoneNumber Ya Nomor telepon kontak, dengan kode negara (contoh: +15551234567).
firstName Tidak Nama depan.
lastName Tidak Nama belakang.
email Tidak Alamat email.
channel Tidak Saluran pesan. Salah satu dari whatsapp, sms, whatsapp_web. Default-nya adalah whatsapp.
is_bot_active Tidak Apakah asisten AI membalas kontak ini. Default-nya adalah true.
is_private Tidak Tandai kontak sebagai pribadi. Jika true, asisten AI dimatikan untuk mereka. Default-nya adalah false.
lead_profile Tidak Catatan teks bebas tentang prospek.
listId Tidak ID daftar tunggal untuk menambahkan kontak.
listIds Tidak Array ID daftar untuk menambahkan kontak (lebih diutamakan daripada listId).
custom_fields Tidak Objek kolom kunci/nilai Anda sendiri. Anda juga dapat mengirimkannya sebagai kunci tingkat atas.

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

Respons

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

ID kontak baru ada di data.contactId. Daftar tempat kontak tersebut ditambahkan akan dikembalikan dalam data.listsAdded.

Duplikat tidak dibuat. Jika kontak dengan nomor telepon yang sama sudah ada, panggilan buat tidak akan membuat atau mengembalikannya. Respons yang muncul adalah status HTTP 200 dan error_code sebesar 409 di dalam body, jadi lakukan percabangan pada error_code alih-alih pada status HTTP:

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

Untuk bekerja dengan kontak yang sudah ada setelah error_code sebesar 409, cari kontak tersebut dengan Dapatkan kontak berdasarkan telepon atau emailGET /contacts?phoneNumber=... — dan gunakan kembali ID yang dikembalikannya.

Ejaan WhatsApp yang setara dihitung sebagai nomor yang sama. Beberapa negara memiliki dua ejaan yang valid untuk saluran seluler yang sama dan WhatsApp mungkin melaporkan salah satunya: Meksiko (+52… dan +521… lama), Brasil (dengan atau tanpa digit kesembilan), dan Argentina (dengan atau tanpa 9 setelah +54). Pemeriksaan duplikat saat pembuatan dan pencocokan GET /contacts?phoneNumber= berlaku untuk kedua ejaan tersebut, sehingga Anda akan mendapatkan kembali kontak yang sudah ada, apa pun bentuk yang Anda kirimkan. phone_number yang tersimpan pada kontak tidak akan pernah ditulis ulang.


Mendapatkan kontak berdasarkan telepon atau email

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

Mencari satu kontak dan mengembalikan objek kontak lengkap yang diperkaya — termasuk daftar, tag, dan kampanye yang diselesaikan menjadi pasangan { id, name }, ditambah pesan terakhir yang dipertukarkan.

Berikan salah satu phoneNumber (dalam format internasional) atau email. Jika Anda tidak memberikan keduanya, endpoint yang sama ini akan beralih ke mode Daftar kontak.

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

Respons

{
  "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 kontak dikembalikan baik di tingkat atas (contactId) maupun di dalam objek (contact.id). Jika tidak ada yang cocok, Anda akan mendapatkan 404 dengan { "success": false, "message": "Contact not found" }.

avatarUrl adalah foto profil kontak, yang diambil dari WhatsApp atau Meta saat mereka mengirim pesan kepada Anda. Ini bersifat baca-saja: Anda tidak dapat mengaturnya, dan ini adalah null untuk kontak yang tidak memiliki foto atau yang menghubungi Anda melalui saluran yang tidak membagikannya. Perlakukan tautan tersebut sebagai sementara alih-alih menyimpannya, karena beberapa tautan foto ini kedaluwarsa dan diperbarui secara otomatis. (Dalam endpoint daftar di bawah, nilai yang sama disebut avatar_url.)

Nomor telepon di URL. Tanda + dalam string kueri harus di-encode URL sebagai %2B, jika tidak, tanda tersebut akan dibaca sebagai spasi. Contoh di atas sudah melakukannya untuk Anda.


Mendapatkan kontak berdasarkan ID

GET /contacts/{contactId}

Jika Anda sudah memiliki ID kontak, ambil datanya secara langsung. Bentuk responsnya identik dengan pencarian di atas.

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

ID kontak yang tidak ada di akun Anda akan mengembalikan 404.


Mendapatkan statistik kontak

GET /contacts/{contactId}/stats

Mengembalikan statistik pesan gabungan untuk satu kontak: total, balasan AI vs manusia, kredit yang digunakan, serta stempel waktu pesan pertama/terakhir.

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

Respons

{
  "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 adalah penghitung pesan AI yang sama dengan yang diatur ulang oleh tombol “reset” dalam aplikasi pada sebuah kontak. creditsUsed adalah total kredit berjalan untuk kontak ini, bukan hanya angka untuk respons ini saja. ID kontak yang tidak ada di akun Anda akan mengembalikan 404.


Mencantumkan kontak

GET /contacts

Panggil GET /contacts tanpa phoneNumber maupun email untuk menelusuri semua kontak Anda, dimulai dari yang terbaru. Setiap halaman mengembalikan ringkasan kontak yang ringkas (daftar, tag, dan kampanye dikembalikan sebagai array ID, bukan objek lengkap) dan sebuah next_cursor.

Parameter kueri Deskripsi
limit Ukuran halaman. Default-nya 50, maksimum 100.
cursor Nilai next_cursor dari halaman sebelumnya. Hilangkan pada halaman pertama.
listId Opsional. Hanya mengembalikan kontak yang termasuk dalam daftar ini.

Untuk menelusuri setiap halaman: lakukan panggilan pertama tanpa kursor, lalu terus berikan next_cursor yang dikembalikan sebagai cursor. Berhenti saat next_cursor bernilai null — itu berarti tidak ada lagi hasil yang tersisa.

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

Respons

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

Catatan: Memfilter berdasarkan listId yang tidak ada di akun Anda akan mengembalikan 404. cursor yang tidak valid akan mengembalikan 400.


Menghitung kontak

GET /contacts/count

Mengembalikan berapa banyak kontak yang cocok dengan filter, ditambah pembagian per saluran, tanpa perlu melakukan paging. Ini adalah panggilan yang tepat untuk pertanyaan “berapa banyak” — ubin dasbor, otomatisasi, atau bertanya kepada Champ. Semua filter bersifat opsional, dan menggabungkan beberapa filter akan mempersempit jumlahnya (kontak harus cocok dengan setiap filter yang Anda kirim).

Parameter kueri Deskripsi
agentId Hanya kontak yang ditetapkan ke agen AI ini. Berikan none untuk kontak tanpa agen yang ditetapkan (kontak tersebut dijawab oleh agen default saluran).
channel Hanya kontak di saluran ini, contohnya whatsapp, messenger, instagram, sms, email, chat_widget.
tag Hanya kontak yang memiliki tag ini, berdasarkan nama tag (huruf besar/kecil tidak berpengaruh). Nama tag yang tidak Anda miliki akan mengembalikan 404.
listId Hanya kontak di daftar ini.
botActive true atau false — hanya kontak yang asisten AI-nya aktif atau nonaktif.
status Hanya kontak dengan status ini, contohnya Lead.
rules Objek aturan JSON yang di-encode URL, menggunakan bentuk yang sama dengan daftar cerdas (lihat Bentuk smart_rules di bawah). Tidak dapat digabungkan dengan filter lainnya.

Jangan kirim filter apa pun dan Anda akan mendapatkan jumlah total kontak di akun Anda.

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

Respons

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

by_channel membagi total yang sama per saluran; kontak yang tidak ada di saluran mana pun dihitung di bawah none. filters menggemakan kembali filter yang diterapkan, sehingga Anda dapat memeriksa apakah panggilan tersebut melakukan apa yang Anda maksudkan.

Catatan: Mengirim rules bersama dengan filter lain, atau nilai rules yang bukan JSON valid, akan mengembalikan 400. Nama tag atau ID daftar yang tidak ada di akun Anda akan mengembalikan 404.


Memperbarui kontak

PUT /contacts/{contactId}

Memperbarui kontak yang sudah ada. Hanya kolom yang Anda sertakan yang akan diubah — abaikan kolom yang tidak ingin Anda ubah. Anda harus mengirim setidaknya satu kolom, atau Anda akan mendapatkan 400 (“Tidak ada kolom untuk diperbarui”).

Bidang Deskripsi
firstName Nama depan.
lastName Nama belakang.
email Alamat email.
is_bot_active Apakah asisten AI membalas kontak ini.
is_private Tandai sebagai pribadi. Mengatur ini ke true juga akan mematikan asisten AI.
do_not_disturb Jeda penjangkauan otomatis ke kontak ini. Juga menghentikan AI untuk membalas.
follow_ups_disabled Hentikan semua tindak lanjut otomatis untuk kontak ini (cepat, siklus, dan prospek dingin) sementara AI tetap membalas pesan yang mereka kirim. Berguna setelah seseorang melakukan pembelian. Tetap nonaktif hingga Anda mengaturnya kembali ke false.
lead_profile Catatan prospek teks bebas.
custom_fields Objek bidang kustom. Digabungkan per kunci — hanya kunci yang Anda kirim yang akan ditulis, sisa bidang kustom yang ada akan tetap dipertahankan. Anda juga dapat meneruskan kunci bidang kustom di tingkat atas.

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

Respons

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

Kolom kustom digabungkan, bukan diganti. Mengirim { "custom_fields": { "tier": "gold" } } hanya akan mengatur tier — kolom kustom lainnya pada kontak akan tetap seperti semula. Untuk menghapus kolom kustom sepenuhnya di semua kontak, gunakan Hapus kolom kustom.


Menambah atau menghapus tag

POST /contacts/{contactId}/tags

Menambah dan/atau menghapus tag pada satu kontak dalam satu panggilan. Teruskan ID tag di addTagIds dan removeTagIds. Setidaknya salah satu dari keduanya harus tidak kosong.

Tag tersebut harus sudah ada di akun Anda — buat tag terlebih dahulu melalui endpoint tag. Jika kontak atau tag yang dirujuk tidak ada, Anda akan mendapatkan 404.

Bidang Deskripsi
addTagIds Larik ID tag untuk ditambahkan ke kontak.
removeTagIds Larik ID tag untuk dihapus dari kontak.

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

Respons

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

Mengelola pustaka tag Anda

Endpoint ini mengelola tag itu sendiri — mengganti nama atau menghapusnya dari akun Anda — berbeda dengan menerapkan atau menghapus tag pada satu kontak (lihat Menambah atau menghapus tag di atas). Setiap tag di akun Anda memiliki ID (tagId): ID yang ditampilkan di pengelola tag dasbor Anda, dan ID yang dikembalikan sebagai data.tag_id saat Anda membuat tag dengan POST /tags dan badan JSON { "name": "..." } (tanpa phoneNumber, email, atau contactId).

Memperbarui tag

PUT /tags/{tagId}

Kirim hanya kolom yang ingin Anda ubah.

Kolom Deskripsi
name Nama tag.
curl -X PUT "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags/tagHotLead?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Hot lead (Q3)" }'

Respons

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

tagId yang tidak ada di akun Anda akan mengembalikan 404.

Menghapus tag

DELETE /tags/{tagId}

Menghapus satu tag berdasarkan ID. Tindakan ini tidak dapat dibatalkan — kontak yang memiliki tag tersebut akan kehilangan tag tersebut. Menghapus tag yang sudah tidak ada (atau tidak pernah ada) akan mengembalikan 200 dengan deleted: 0 alih-alih 404, karena tidak ada yang perlu dihitung.

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

Respons

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

Menghapus beberapa tag sekaligus

DELETE /tags

Field Description
tagIds Array ID tag untuk dihapus (maks 1000).
curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tagIds": ["tagColdLead", "tagUnsubscribed"] }'

Respons

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

ID yang tidak ada, atau milik akun lain, akan dilewati secara diam-diam dan tidak dihitung dalam deleted.


Mengatur flag secara massal

POST /contacts/bulk-flag

Mengatur satu flag boolean pada banyak kontak sekaligus. Hingga 500 ID kontak per permintaan. ID yang tidak ada di akun Anda akan dilewati dan dihitung dalam skipped.

Bidang Deskripsi
contactIds Larik ID kontak untuk diperbarui (maks 500).
field Flag mana yang akan diatur. Salah satu dari bot_active (asisten AI aktif/nonaktif), dnd (jeda jangkauan otomatis), spam, private.
value Nilai boolean untuk mengatur flag tersebut.

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

Respons

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

Impor kontak massal

POST /contacts/import

Membuat hingga 500 kontak dalam satu panggilan dari array JSON. Setiap catatan memerlukan phone_number dalam format internasional; sisanya bersifat opsional. Catatan dengan nomor telepon yang tidak valid atau saluran yang tidak didukung akan dilewati (tidak dibuat), dan setiap catatan yang dilewati akan dilaporkan beserta indeks dan alasannya — sehingga Anda dapat memperbaiki kegagalan tersebut dan mencoba lagi.

Nomor telepon yang sudah ada di akun Anda akan dilewati sebagai duplicate secara default. Kirim updateExisting: true untuk memperbarui kontak tersebut sebagai gantinya: bidang yang ada dalam catatan akan menimpa data kontak (first_name, last_name, email, lead_profile, dan custom_fields digabungkan per kunci), tags akan ditambahkan, dan kontak akan ditambahkan ke listId. Saluran, nomor telepon, dan tanda bot tidak akan pernah diubah pada kontak yang sudah ada.

Anda dapat menambahkan setiap kontak yang diimpor (atau diperbarui) ke daftar dengan listId secara opsional, menetapkan defaultChannel untuk catatan yang tidak menentukannya, dan menandai catatan dengan tags (nama tag — tag yang tidak ada akan dibuat, tag yang sudah ada dicocokkan tanpa mempedulikan huruf besar/kecil).

Bidang tingkat atas

Bidang Wajib Deskripsi
contacts Ya Array catatan kontak (maks 500).
listId Tidak Daftar untuk menambahkan setiap kontak yang diimpor (dan diperbarui). Harus berupa daftar di akun Anda.
defaultChannel Tidak Saluran yang diterapkan ke catatan yang tidak menyertakan channel. Salah satu dari whatsapp, sms, whatsapp_web. Default ke whatsapp.
updateExisting Tidak true untuk memperbarui kontak yang nomor teleponnya sudah ada alih-alih melewatinya sebagai duplicate. Default ke false.

Bidang per catatan

Bidang Wajib Deskripsi
phone_number Ya Nomor telepon dalam format internasional (+ di depan akan ditambahkan jika tidak ada).
first_name Tidak Nama depan.
last_name Tidak Nama belakang.
email Tidak Alamat email.
channel Tidak Salah satu dari whatsapp, sms, whatsapp_web. Kembali ke defaultChannel.
is_bot_active Tidak Apakah asisten AI membalas. Default ke true.
is_private Tidak Tandai pribadi. Default ke false.
lead_profile Tidak Catatan prospek teks bebas.
custom_fields Tidak Objek kunci dan nilai bidang kustom.
tags Tidak Array nama tag (satu string "a; b" juga berfungsi). Tag yang tidak ada akan dibuat; tag yang sudah ada dicocokkan dengan mengabaikan huruf besar/kecil. Maks 25 per catatan.

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

Respons

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

Jika beberapa catatan tidak dapat dibuat, catatan tersebut akan muncul di skipped beserta alasannya (di sini tanpa updateExisting, sehingga nomor yang sudah ada dilewati):

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

Dengan updateExisting: true, permintaan yang sama akan melaporkan kontak yang sudah ada di bawah updated / updated_contact_ids sebagai gantinya.

Kemungkinan alasan dilewati: invalid_record, missing_phone_number, invalid_phone_number, invalid_channel, duplicate_in_request, duplicate, contact_limit_reached, create_failed.

Batas paket. Jika batas kontak paket Anda tidak memungkinkan penambahan kontak sebanyak ini, seluruh permintaan akan ditolak di awal dengan 403. Jika batas tercapai di tengah proses, catatan yang tersisa akan dikembalikan sebagai dilewati dengan alasan contact_limit_reached.


Impor kontak dari file CSV

Untuk impor yang lebih besar dari yang didukung oleh impor massal (hingga sekitar 50.000 baris), antrekan pekerjaan impor asinkron terhadap file CSV yang sudah ada di penyimpanan akun Anda, lalu lakukan polling hingga selesai.

Memulai impor

POST /contacts/import-csv

Field Wajib Deskripsi
csvStoragePath Ya Jalur penyimpanan file CSV, di bawah users/{your account id}/imports/, diakhiri dengan .csv.
listName Ya Membuat (atau menggunakan kembali) daftar dengan nama ini dan menambahkan setiap kontak yang diimpor ke dalamnya.
existingListRefs Tidak Array ID daftar yang ada untuk juga menambahkan setiap kontak yang diimpor ke dalamnya.
defaultChannel Tidak Saluran yang diterapkan ke baris yang tidak menentukannya.
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"]

Respons (202 — impor sedang diantrekan, belum selesai)

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

Memasukkan file ke penyimpanan. Endpoint ini memulai dan melacak pekerjaan impor; endpoint ini tidak menerima unggahan secara langsung. File CSV harus sudah berada di csvStoragePath sebelum Anda memanggilnya — pengimpor CSV dasbor itu sendiri melakukan ini sebagai langkah pertamanya.

Polling pekerjaan impor

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"

Respons

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

status bergerak melalui queuedprocessingcompleted, atau failed dengan alasan di error_message. jobId yang tidak ada di akun Anda akan mengembalikan 404.


Ekspor kontak

Memulai ekspor CSV asinkron dari kontak Anda dan mengembalikan pekerjaan yang dapat Anda polling untuk penyelesaiannya.

Memulai ekspor

POST /contacts/export

Bidang Wajib Deskripsi
listId Tidak Hanya ekspor kontak yang termasuk dalam daftar ini.
contactIds Tidak Hanya ekspor ID kontak spesifik ini.

Jika keduanya dikosongkan, semua kontak di akun Anda akan diekspor.

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

Respons (202 — ekspor sedang dalam antrean)

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

Memeriksa status pekerjaan ekspor

GET /contacts/export/{jobId}

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

Respons

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

Setelah status berstatus "completed", Anda akan mendapatkan export_id dan contact_count. Pengunduhan file CSV yang dihasilkan dilakukan melalui halaman Ekspor di dasbor Anda.


Kirim pesan ke kontak

POST /contacts/{contactId}/send-message

Mengirim pesan ke kontak yang sudah ada di saluran mana pun yang sedang mereka gunakan. Pesan akan diantrekan dan dikirim di latar belakang — respons mengonfirmasi bahwa pesan telah diterima, bukan bahwa pesan tersebut sudah terkirim.

Bidang Wajib Deskripsi
body Ya Teks pesan yang akan dikirim.
mediaUrl Tidak URL file media untuk dilampirkan.
mediaContentType Tidak Tipe MIME dari media yang dilampirkan (contoh: 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"])

Respons

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

Tidak dapat mengirim sekarang? Jika kontak mengaktifkan mode jangan ganggu atau mode pribadi, atau tidak berada di saluran yang dapat menerima pesan keluar, permintaan akan ditolak dengan 422 dan error yang menjelaskan alasannya.

Untuk mengirim melalui nomor telepon, ID Instagram, atau identitas saluran lainnya alih-alih ID kontak — dan untuk informasi lebih lanjut tentang pengiriman pesan secara umum — lihat Messages API.


Menetapkan agen AI ke kontak

POST /contacts/{contactId}/assign-agent

Memindahkan percakapan yang sudah ada ke agen AI yang berbeda, mulai dari pesan berikutnya. Tindakan ini sama dengan Tetapkan Agen AI di menu obrolan, dan langkah yang sama yang digunakan oleh tindakan Tetapkan agen atau kampanye AI dalam Otomatisasi.

Bidang Wajib Deskripsi
agentId Ya ID agen AI yang harus mengambil alih, atau null untuk menghapus penetapan agar percakapan kembali ke kotak masuk tim Anda.
triggerAIResponse Tidak true membuat agen yang baru ditetapkan langsung membalas pesan kontak yang belum terjawab. Default-nya adalah false.

Berhati-hatilah dengan triggerAIResponse: true — ini mengirim pesan ke kontak saat itu juga, jadi gunakan hanya jika Anda ingin mereka dikirimi pesan sekarang. Di Messenger dan Instagram, pesan tersebut gagal jika kontak terakhir menulis kepada Anda lebih dari 24 jam yang lalu.

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

Respons

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

Agen harus berasal dari akun yang sama dengan kontak; jika tidak, permintaan akan ditolak dengan 404 atau 403. Temukan ID agen di halaman Agen AI (URL setiap agen diakhiri dengan ID-nya).


Menetapkan agen AI ke banyak kontak

POST /contacts/bulk-assign-agent

Memindahkan banyak percakapan ke agen AI yang berbeda dalam satu panggilan — atau menghapus penetapan untuk semuanya dengan null. Ini murni perubahan perutean: tidak ada pesan yang dikirim dan agen tidak membalas siapa pun. Setiap kontak cukup mendapatkan agen baru saat mereka menulis pesan berikutnya. (Itulah sebabnya tidak ada triggerAIResponse di sini.)

Bidang Wajib Deskripsi
agentId Ya Agen AI yang harus mengambil alih, atau null untuk menghapus penetapan.
contactIds Salah satu dari tiga Hingga 500 ID kontak untuk dipindahkan.
filter Salah satu dari tiga Pilih kontak di server alih-alih mencantumkannya, yang terbaru terlebih dahulu. Menggunakan kunci yang sama dengan filter endpoint hitung: agentId (atau none), channel, tag, listId, botActive, status.
rules Salah satu dari tiga Objek aturan daftar cerdas — lihat Bentuk smart_rules.
limit Tidak Berapa banyak kontak yang akan dipindahkan dalam panggilan ini saat Anda memilih dengan filter atau rules. 1 hingga 500, defaultnya 500.

Kirim tepat satu dari contactIds, filter, atau 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"])

Respons

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

matched adalah berapa banyak kontak yang ditemukan oleh pilihan tersebut secara total, updated berapa banyak yang dipindahkan oleh panggilan ini, skipped berapa banyak ID yang Anda kirim tidak ditemukan di akun Anda, dan remaining berapa banyak yang masih cocok sekarang setelah panggilan ini selesai.

Memindahkan semua orang. Karena satu panggilan memindahkan paling banyak 500 kontak, grup besar memerlukan beberapa panggilan. Gunakan filter yang berhenti mencocokkan kontak setelah dipindahkan — misalnya filter: { "agentId": "agent_abc123" } saat menetapkan ke agent_xyz789 — dan ulangi panggilan yang sama persis hingga remaining kembali sebagai 0. Saat Anda memberikan contactIds sebagai gantinya, remaining selalu 0.


Menetapkan kontak ke departemen

POST /contacts/{contactId}/department

“Tetapkan prospek ini ke Penjualan” — mengarsipkan kontak di bawah departemen tertentu dan, secara default, menyerahkannya kepada siapa pun di departemen tersebut yang saat ini memiliki kontak paling sedikit. Ini terpisah dari menetapkan agen AI: departemen menjawab “tim mana yang memiliki ini,” agen menjawab “AI mana yang menjawab ini,” dan menetapkan salah satunya tidak akan pernah menghapus yang lain.

Bidang Wajib Deskripsi
department_id Ya Departemen tempat kontak akan diarsipkan. Berikan null untuk menghapusnya.
hand_to_member Tidak Juga serahkan kontak kepada orang dengan beban kerja paling sedikit di departemen tersebut. Default-nya adalah true. Tidak akan pernah menetapkan ulang kontak yang sudah dimiliki seseorang.

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

Respons

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

assigned_to bernilai null jika kontak tersebut sudah dimiliki oleh seseorang, atau Anda memberikan hand_to_member: false.


Menautkan kontak lintas saluran

“Lanjutkan di WhatsApp” (atau SMS) akan mencari atau membuat kontak orang ini di saluran berbasis telepon lain dan menautkan keduanya, sehingga aplikasi mengenali mereka sebagai orang yang sama.

Tautkan ke saluran lain

POST /contacts/{contactId}/link-channel

Bidang Wajib Deskripsi
channel Ya Saluran untuk ditautkan. Salah satu dari whatsapp, whatsapp_web, sms.
phoneNumber Tidak Nomor telepon yang digunakan pada saluran baru. Default-nya adalah nomor kontak sumber itu sendiri.
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" }'

Respons

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

created memberi tahu Anda apakah kontak baru dibuat untuk saluran target atau kontak yang sudah ada ditemukan dan ditautkan. Memanggil ini untuk kedua kalinya aman — fungsi ini mengembalikan contact_id yang sama dengan created: false alih-alih membuat duplikat.

422 berarti akun tidak dapat melakukan penautan ini saat ini: kontak sudah berada di keluarga saluran tersebut, tidak memiliki nomor telepon untuk digunakan, atau tidak ada pengirim yang terhubung untuk saluran target. 409 berarti kedua kontak sudah ditautkan ke dua orang yang berbeda — batalkan tautan salah satunya terlebih dahulu.

Mencantumkan percakapan yang ditautkan dari kontak

GET /contacts/{contactId}/linked

Mengembalikan percakapan lain yang merupakan orang yang sama dengan kontak ini. Kontak yang tidak ditautkan akan mengembalikan array kosong, bukan 404 — “orang ini tidak memiliki saluran lain” adalah status yang normal.

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

Respons

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

Batalkan tautan kontak

DELETE /contacts/{contactId}/link

Menghapus kontak ini dari orangnya, secara sepihak — kontak lain yang masih ditautkan ke orang tersebut tetap mempertahankan tautannya, jadi membatalkan tautan satu dari tiga kontak tidak akan membubarkan grup tersebut.

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

Respons

{ "success": true }

Mengambil foto profil kontak

POST /contacts/{contactId}/profile-pic

Mengambil (dan menyimpan dalam cache) foto profil WhatsApp atau Meta kontak sesuai permintaan — foto yang sama dikembalikan sebagai avatarUrl pada Dapatkan kontak, yang diperbarui.

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

Respons

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

cached: true berarti URL berasal dari pengambilan terbaru, bukan pencarian penyedia yang baru — foto disimpan dalam cache selama 7 hari, dan kontak yang menurut penyedia tidak memiliki foto yang dapat dijangkau akan disimpan dalam cache sebagai tidak tersedia selama 24 jam. Jika tidak ada foto untuk diambil, avatar_url dihilangkan dan message menjelaskan alasannya.


Menandai kontak secara otomatis dengan AI

Menjalankan aturan tag akun Anda pada riwayat percakapan lengkap satu atau beberapa kontak dan menerapkan (atau menghapus) tag persis seperti penandaan waktu nyata yang berjalan selama obrolan langsung — aturan yang sama, biaya kredit per tag yang sama.

Memulai proses

POST /contacts/auto-tag

Bidang Wajib Deskripsi
scope Ya "contacts" untuk menandai kontak tertentu, atau "agent" untuk menandai setiap percakapan yang saat ini ditangani oleh satu agen AI.
contact_ids Wajib jika scope adalah "contacts" Larik ID kontak, 1 hingga 500.
agent_id Wajib jika scope adalah "agent" Agen AI yang percakapannya akan ditandai. Jika scope adalah "contacts", bidang ini bersifat opsional dan hanya mempersempit aturan tag agen mana yang dijalankan.
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"] }'

Satu kontak dijalankan secara inline dan langsung mengembalikan hasilnya:

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

Dua atau lebih kontak (atau scope: "agent") dijalankan sebagai tugas latar belakang dan langsung mengembalikan 202:

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

Melakukan polling proses

GET /contacts/auto-tag/run

Mengembalikan proses akun saat ini (atau yang terbaru), sehingga Anda dapat melakukan polling kemajuan tanpa harus melacak run_id sendiri.

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

Respons

{
  "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 adalah null jika akun belum pernah memulai satu proses pun. status berpindah dari "running" ke "completed" atau "failed".

Hanya satu proses massal yang dapat berjalan per akun dalam satu waktu — memulai proses kedua saat proses lain sedang berjalan akan mengembalikan 409 dengan error_code: "auto_tag_run_in_progress". Kehabisan kredit pada proses satu kontak akan mengembalikan 402 dengan error_code: "insufficient_credits"; proses massal justru akan berhenti lebih awal dan melaporkan sejauh mana proses tersebut berjalan di run.


Menghapus kontak

DELETE /contacts/{contactId}

Menghapus satu kontak secara permanen berdasarkan ID, beserta riwayat pesannya. Tindakan ini tidak dapat dibatalkan. Untuk menghapus beberapa kontak dalam satu panggilan, gunakan Hapus kontak di bawah ini.

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

Respons

{
  "success": true
}

ID kontak yang tidak ada di akun Anda, atau milik akun yang berbeda, akan mengembalikan 404.


Menghapus kontak

DELETE /contacts

Menghapus satu atau beberapa kontak secara permanen berdasarkan ID dalam satu panggilan (hingga 500 ID). ID yang tidak ada di akun Anda akan dilewati dan dihitung dalam skipped. Tindakan ini tidak dapat dibatalkan.

Bidang Deskripsi
contactIds Larik ID kontak yang akan dihapus (maks 500).

cURL

curl -X DELETE "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactIds": ["contactId1", "contactId2"] }'

JavaScript

const res = await fetch("<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts", {
  method: "DELETE",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ contactIds: ["contactId1", "contactId2"] }),
});
const data = await res.json();
console.log(`Deleted ${data.deleted}, skipped ${data.skipped}`);

Python

import requests

res = requests.delete(
    "<span data-t="apiBaseUrl">https://api.youraiconnector.com</span>/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"contactIds": ["contactId1", "contactId2"]},
)
data = res.json()
print(f"Deleted {data['deleted']}, skipped {data['skipped']}")

Respons

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

Menghapus bidang kustom

DELETE /contacts/custom-fields/{fieldKey}

Menghapus satu kunci bidang kustom dari setiap kontak di akun Anda. Gunakan ini untuk membersihkan data setelah mengganti nama atau menonaktifkan bidang kustom. Kunci hanya boleh berisi huruf, angka, garis bawah, dan tanda hubung. Mengembalikan jumlah kontak yang diperbarui. Tindakan ini tidak dapat dibatalkan.

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

Respons

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

Catatan: Kunci kolom dengan karakter yang tidak didukung akan mengembalikan 400.


Daftar

Daftar mengelompokkan kontak. Daftar bisa berupa statis (Anda yang menentukan siapa yang ada di dalamnya) atau cerdas (keanggotaan dihitung berdasarkan aturan dan diperbarui secara otomatis — lihat Mengatur Daftar & Kontak).

Bidang Deskripsi
name Wajib diisi saat pembuatan. Maksimal 100 karakter.
status live (default) atau draft. Huruf kecil.
contact_ids Larik ID kontak untuk dimasukkan ke dalam daftar. Hanya untuk daftar statis.
type static (default) atau smart.
smart_rules Kumpulan aturan — wajib diisi saat type adalah smart. Lihat di bawah.

Membuat daftar

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

Respons

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

Daftar cerdas dievaluasi secara inline, dalam permintaan yang sama, sehingga evaluation memberi tahu Anda dengan tepat siapa saja yang masuk ke dalamnya. Pada daftar statis, evaluation adalah null.

Memperbarui daftar

PUT /lists/{listId}

Kirim hanya bidang yang ingin Anda ubah. Mengubah smart_rules akan mengevaluasi ulang daftar secara langsung dan mengembalikan objek evaluation yang sama.

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

Anda dapat mengubah jenis daftar di antara keduanya:

  • Statis → cerdas: kirim { "type": "smart", "smart_rules": { … } }. Aturan akan langsung diterapkan.
  • Cerdas → statis: kirim { "type": "static" }. Aturan akan dihapus dan siapa pun yang ada di dalam daftar akan tetap berada di sana.

Bentuk 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 (setiap kondisi harus benar) atau any (setidaknya satu).
  • conditions — 1 hingga 20 kondisi, masing-masing maksimal 100 nilai, string hingga 200 karakter.
field op value
tags has_any, has_all, has_none larik ID tag
lists in_any, not_in_any larik ID daftar (hanya daftar statis — daftar cerdas tidak dapat dibuat dari daftar cerdas lainnya)
channel is_any, is_none larik saluran
status is_any, is_none larik status kontak
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" }
kolom tanggal yang sama before, after tanggal ISO ("2026-01-01", dibandingkan sebagai hari penuh) atau tanggal-waktu ISO lengkap ("2026-01-01T14:30:00Z", dibandingkan hingga momen yang tepat)
kolom tanggal yang sama is_set, not_set
has_interacted_with_ai is true / falsetrue mencocokkan kontak yang pernah dikirimi pesan oleh AI setidaknya sekali (kapan pun)
is_bot_active, do_not_disturb, is_private, has_ever_responded is true / false
email, phone_number, first_name, last_name is_set, not_set, contains, not_contains string untuk formulir contains
current_campaign_id, assigned_agent is_any, is_none, is_set, not_set larik ID untuk formulir is_any / is_none
custom_field (ditambah key) eq, neq, contains, not_contains, is_set, not_set string untuk formulir nilai

not_within_last juga mencocokkan kontak yang tanggalnya tidak pernah ditetapkan (“lebih dari N yang lalu, atau tidak pernah”), dan perbandingan teks mengabaikan huruf besar/kecil.

Keterlibatan AI. has_interacted_with_ai adalah penanda seumur hidup: true untuk setiap kontak yang telah dikirimi setidaknya satu pesan oleh AI Anda, false untuk yang lainnya (termasuk kontak yang hanya pernah dijawab oleh tim Anda). Penanda ini dibubuhkan pada pesan pertama AI ke kontak dan tidak pernah dihapus, jadi mematikan balasan AI untuk kontak tersebut atau memindahkan mereka ke kampanye lain tidak akan meresetnya. Untuk periode — “kontak yang ditangani AI saya bulan ini”, pertanyaan penagihan yang umum — gunakan rentang last_ai_interaction_at sebagai gantinya:

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

Jangan tertukar dengan is_bot_active (AI diizinkan untuk membalas, bukan berarti sudah membalas) atau has_ever_responded (kontak membalas, kepada siapa pun). Kedua penanda yang sama dikembalikan pada setiap kontak sebagai first_ai_interaction_at / last_ai_interaction_at, dan seluruh rangkaian aturan juga berfungsi pada GET /contacts?rules=, sehingga Anda dapat menghitung kecocokan tanpa membuat daftar.

Pratinjau kumpulan aturan

POST /lists/preview

Menghitung dan mengambil sampel kontak yang akan dicocokkan oleh kumpulan aturan, tanpa membuat atau mengubah apa pun. Gunakan ini untuk memeriksa kewajaran aturan sebelum Anda menyimpannya.

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

Respons

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

sample menampung hingga 10 kontak, dengan yang paling baru aktif di urutan pertama.

Jalankan ulang daftar cerdas sekarang

POST /lists/{listId}/evaluate

Memaksa evaluasi ulang segera (sama dengan fungsi Segarkan sekarang di dasbor). Daftar cerdas sudah diperbarui saat kontak berubah, dan setiap 15 menit untuk aturan berbasis waktu, jadi ini hanya diperlukan saat Anda menginginkan hasilnya saat ini juga.

Respons

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

evaluation.skipped: true berarti evaluasi lain dari daftar yang sama sudah berjalan dan panggilan ini tidak melakukan apa pun.

Daftar cerdas menolak anggota yang dipilih secara manual

Endpoint keanggotaan mengembalikan 409 dengan "This is a smart list — its members are computed from its rules. Edit the rules instead." saat daftar target adalah daftar cerdas. Ini mencakup POST /contacts/lists, DELETE /contacts/lists, POST /contacts/lists/batch, contact_ids pada POST /lists dan PUT /lists/{listId}, serta memilih daftar cerdas sebagai target impor CSV. Ubah aturannya sebagai gantinya.

Memanggil POST /lists/{listId}/evaluate pada daftar statis juga merupakan 409 — daftar tersebut tidak memiliki aturan untuk dijalankan.


Kesalahan API Kontak

Endpoint kontak mengembalikan amplop error standar:

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

Beberapa endpoint juga menyertakan error_code, yang biasanya cocok dengan status HTTP — satu-satunya pengecualian adalah kasus kontak duplikat di bawah, di mana status HTTP adalah 200 dan hanya error_code yang membawa 409. Kode yang spesifik untuk endpoint kontak:

Kode Kapan ini terjadi pada endpoint kontak
400 Permintaan buruk — kolom yang hilang/tidak valid, isi kosong, kursor buruk, atau lebih dari 500 ID dalam satu batch.
402 Kredit tidak cukup untuk menyelesaikan proses penandaan AI pada satu kontak (error_code: "insufficient_credits").
404 Kontak, daftar, atau tag tidak ditemukan di akun Anda.
409 Kontak dengan nomor telepon tersebut sudah ada (saat pembuatan). Dikembalikan sebagai error_code di dalam isi dengan status HTTP 200, jadi buat percabangan pada error_code di sini. Juga dikembalikan saat proses penandaan otomatis massal sedang berlangsung (error_code: "auto_tag_run_in_progress"), atau saat menautkan kontak ke saluran lain yang akan menggabungkan dua kontak yang sudah ditautkan ke dua orang berbeda.
422 Kontak tidak dapat menerima pesan saat ini (jangan ganggu, pribadi, atau saluran yang tidak didukung). Pada endpoint penautan saluran, ini juga mencakup tidak ada nomor telepon, pemasangan saluran yang tidak didukung, atau tidak ada pengirim yang terhubung untuk saluran target.

403 pada endpoint kontak juga dapat berarti masalah batas kontak atau izin daftar, bukan akses paket. Kode bersama yang dapat dikembalikan oleh setiap endpoint — 401, 403 (paket Anda tidak menyertakan akses API), 429 (batas kecepatan), dan 500 — tercantum beserta panduan percobaan ulang di Kesalahan & Penomoran Halaman.


Langkah berikutnya

  • API Pesan — mengirim pesan berdasarkan identitas saluran dan mengelola percakapan.
  • Referensi API — daftar endpoint lengkap, termasuk tag dan daftar.
  • Akses API — autentikasi, batas kecepatan, dan penanganan error.