Sikio API · v1
Contacts API
Connect your CRM to the same customer records used by Sikio’s inbox. Each credential is restricted to its own workspace.
Find contacts
Use contacts:read. Contact pagination is page-based; the page size is capped at 100.
curl --fail-with-body \
--user 'YOUR_API_KEY:YOUR_API_SECRET' \
--write-out '\nHTTP %{http_code}\n' \
'https://stage.api.ictlife.com/v1/integrations/contacts'const credentials = Buffer.from('YOUR_API_KEY:YOUR_API_SECRET').toString('base64');
const response = await fetch("https://stage.api.ictlife.com/v1/integrations/contacts", {
method: 'GET',
headers: {
Authorization: 'Basic ' + credentials,
},
});
const text = await response.text();
if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);
console.log(response.status, text ? JSON.parse(text) : null);import base64, json
import urllib.request, urllib.error
credentials = base64.b64encode(b'YOUR_API_KEY:YOUR_API_SECRET').decode()
headers = {'Authorization': 'Basic ' + credentials}
request = urllib.request.Request("https://stage.api.ictlife.com/v1/integrations/contacts", method='GET', headers=headers)
try:
with urllib.request.urlopen(request, timeout=30) as response:
text = response.read().decode()
print(response.status, json.loads(text) if text else None)
except urllib.error.HTTPError as error:
raise SystemExit(f'HTTP {error.code}: {error.read().decode()}')The response contains contacts and pagination. Use the contact’s numeric id for subsequent reads or updates. GET /v1/integrations/contact_profile_fields returns the workspace’s custom field definitions in profile_fields.
Synchronize by identity
Use contacts:write and POST /v1/integrations/contacts/upsert. Supply at least one phone, WhatsApp or email identity. Phone numbers are normalized to digits and emails to lowercase for matching. Conflicting identities are rejected rather than merging unrelated contacts.
Replace the sample name, WhatsApp number and email with your contact’s details. Set consent_status from recorded consent; creating a contact does not grant permission to message them.
curl --fail-with-body \
--user 'YOUR_API_KEY:YOUR_API_SECRET' \
--write-out '\nHTTP %{http_code}\n' \
--request POST \
--header 'Content-Type: application/json' \
--data-binary @- \
'https://stage.api.ictlife.com/v1/integrations/contacts/upsert' <<'JSON'
{
"display_name": "Amina Customer",
"whatsapp_number": "+254700000001",
"email": "amina@example.com",
"consent_status": "unknown"
}
JSONconst credentials = Buffer.from('YOUR_API_KEY:YOUR_API_SECRET').toString('base64');
const response = await fetch("https://stage.api.ictlife.com/v1/integrations/contacts/upsert", {
method: 'POST',
headers: {
Authorization: 'Basic ' + credentials,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"display_name": "Amina Customer",
"whatsapp_number": "+254700000001",
"email": "amina@example.com",
"consent_status": "unknown"
}),
});
const text = await response.text();
if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);
console.log(response.status, text ? JSON.parse(text) : null);import base64, json
import urllib.request, urllib.error
credentials = base64.b64encode(b'YOUR_API_KEY:YOUR_API_SECRET').decode()
headers = {'Authorization': 'Basic ' + credentials}
body = json.dumps({
"display_name": "Amina Customer",
"whatsapp_number": "+254700000001",
"email": "amina@example.com",
"consent_status": "unknown"
}).encode()
headers['Content-Type'] = 'application/json'
request = urllib.request.Request("https://stage.api.ictlife.com/v1/integrations/contacts/upsert", method='POST', headers=headers, data=body)
try:
with urllib.request.urlopen(request, timeout=30) as response:
text = response.read().decode()
print(response.status, json.loads(text) if text else None)
except urllib.error.HTTPError as error:
raise SystemExit(f'HTTP {error.code}: {error.read().decode()}'){
"action": "create",
"contact": {
"id": 91,
"display_name": "Amina Customer",
"whatsapp_number": "+254700000001",
"email": "amina@example.com",
"consent_status": "unknown"
}
}action is create or update. Store the returned contact ID. The example shows the contact fields used here; additional saved fields can be returned.
Update or remove
Use PATCH /v1/integrations/contacts/{contact_id} for partial updates. Omitted fields remain unchanged. Profile values belong in profile_data and must match the workspace’s field schema.
DELETE /v1/integrations/contacts/{contact_id} requires the separate contacts:delete permission and soft-deletes the contact. A successful deletion returns HTTP 204 without a body.
See all contact endpoints and fields.
Next guideDelivery, errors and safe retries →