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
200danerror_codesebesar409di dalam body, jadi lakukan percabangan padaerror_codealih-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_codesebesar409, cari kontak tersebut dengan Dapatkan kontak berdasarkan telepon atau email —GET /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 tanpa9setelah+54). Pemeriksaan duplikat saat pembuatan dan pencocokanGET /contacts?phoneNumber=berlaku untuk kedua ejaan tersebut, sehingga Anda akan mendapatkan kembali kontak yang sudah ada, apa pun bentuk yang Anda kirimkan.phone_numberyang 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" }.
avatarUrladalah 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 adalahnulluntuk 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 disebutavatar_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 mengaturtier— 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 alasancontact_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
csvStoragePathsebelum 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 queued → processing → completed, 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
statusberstatus"completed", Anda akan mendapatkanexport_iddancontact_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
422danerroryang 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
404atau403. 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" }
]
}
match—all(setiap kondisi harus benar) atauany(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 / false — true 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.