ChatKomodo Docs Home Sign in

API reference · Messaging

Devices

A device is one WhatsApp number linked to ChatKomodo (shown as a session in the API: its id is the sessionId in the paths). Create one, scan its QR code from WhatsApp → Linked devices (or use a pairing code), then send through it. GET /v1/sessions lists them with their status.

List devices

GET/v1/sessions

List all WhatsApp devices for the calling tenant.

Responses

  • 200List of sessions
    Response fields
    • sessionsarray of objectrequired
    • sessions[].idstringrequired
      ULID identifier
    • sessions[].statusstringrequired
      pending (starting), qr_ready (waiting for a scan), connected, disconnected (was working, connection lost) or failed
      One of: pending, qr_ready, connected, disconnected, failed
    • sessions[].phone_numberstring | nullrequired
      Paired WhatsApp number as digits with country code (no +), e.g. 447700900123
    • sessions[].wa_namestring | nullrequired
      WhatsApp display name, read from the phone when it is linked (no need to type it)
    • sessions[].wa_aboutstring | null
      The number's WhatsApp "About" text (bio), read after linking and refreshed whenever the profile is fetched. "" = no About; null = not read yet or hidden by the phone's privacy settings
    • sessions[].phone_displaystring | null
      The number in international format with its country code, e.g. +44 7700 900123
    • sessions[].phone_countrystring | null
      ISO 3166-1 alpha-2 country of the number, e.g. GB (null when unknown)
    • sessions[].phone_country_codestring | null
      Country calling code with +, e.g. +44
    • sessions[].api_key_idstringrequired
      Owning tenant
    • sessions[].warmup_until_msinteger | nullrequired
      Pacing until this timestamp (anti-ban)
    • sessions[].created_atintegerrequired
    • sessions[].connected_atinteger | nullrequired
  • 401Unauthorized
Request
curl "https://api.chatkomodo.com/v1/sessions" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.get(
    "https://api.chatkomodo.com/v1/sessions",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.chatkomodo.com/v1/sessions', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "sessions": [
    {
      "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "status": "pending",
      "phone_number": "+447700900123",
      "wa_name": "string",
      "wa_about": "string",
      "phone_display": "+447700900123",
      "phone_country": "+447700900123",
      "phone_country_code": "+447700900123",
      "api_key_id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "warmup_until_ms": 1767225600000,
      "created_at": 1767225600000,
      "connected_at": 1767225600000
    }
  ]
}

Create a device

POST/v1/sessions

Create a new WhatsApp device (session). Poll qr_polling_url for the QR code and scan it from WhatsApp, or link with a pairing code (POST /v1/sessions/{id}/pairing-code). Limited by the plan's device quota.

Responses

  • 201Session created
    Response fields
    • idstringrequired
    • statusstringrequired
      One of: pending
    • qr_polling_urlstringrequired
  • 401Unauthorized
  • 403Plan device limit reached
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.post(
    "https://api.chatkomodo.com/v1/sessions",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.chatkomodo.com/v1/sessions', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 201
{
  "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
  "status": "pending",
  "qr_polling_url": "https://example.com/file.jpg"
}

Get a device

GET/v1/sessions/{id}

Get a single session by id.

Path parameters

  • idstringrequired

Responses

  • 200Session detail
    Response fields
    • idstringrequired
      ULID identifier
    • statusstringrequired
      pending (starting), qr_ready (waiting for a scan), connected, disconnected (was working, connection lost) or failed
      One of: pending, qr_ready, connected, disconnected, failed
    • phone_numberstring | nullrequired
      Paired WhatsApp number as digits with country code (no +), e.g. 447700900123
    • wa_namestring | nullrequired
      WhatsApp display name, read from the phone when it is linked (no need to type it)
    • wa_aboutstring | null
      The number's WhatsApp "About" text (bio), read after linking and refreshed whenever the profile is fetched. "" = no About; null = not read yet or hidden by the phone's privacy settings
    • phone_displaystring | null
      The number in international format with its country code, e.g. +44 7700 900123
    • phone_countrystring | null
      ISO 3166-1 alpha-2 country of the number, e.g. GB (null when unknown)
    • phone_country_codestring | null
      Country calling code with +, e.g. +44
    • api_key_idstringrequired
      Owning tenant
    • warmup_until_msinteger | nullrequired
      Pacing until this timestamp (anti-ban)
    • created_atintegerrequired
    • connected_atinteger | nullrequired
  • 404Not found or not owned by tenant
Request
curl "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.get(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
  "status": "pending",
  "phone_number": "+447700900123",
  "wa_name": "string",
  "wa_about": "string",
  "phone_display": "+447700900123",
  "phone_country": "+447700900123",
  "phone_country_code": "+447700900123",
  "api_key_id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
  "warmup_until_ms": 1767225600000,
  "created_at": 1767225600000,
  "connected_at": 1767225600000
}

Delete a device

DEL/v1/sessions/{id}

Closes the live connection, deletes the stored WhatsApp credentials and removes the session together with its auto-reply rules, blast campaigns, blocklist entries and message history. The inbox and scheduled messages are left in place, and WhatsApp is not asked to unlink the device. This cannot be undone.

Path parameters

  • idstringrequired
    Session (device) id

Responses

  • 200Deleted
    Response fields
    • okbooleanrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions, or the operation is not available to CS-agent logins
  • 404Unknown session, or a session of another tenant
Request
curl -X DELETE "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID', {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.delete(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('DELETE', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "ok": true
}

Get the current QR code

GET/v1/sessions/{sessionId}/qr

Returns the QR payload for linking the device: render the qr string with any QR library and scan it from WhatsApp (Linked devices). A code lasts about 60 seconds; qr is null while none is available, so keep polling until status is qr_ready. Answers 410 once the device is connected.

Path parameters

  • sessionIdstringrequired
    Session (device) id

Responses

  • 200Current QR state
    Response fields
    • qrstring | nullrequired
      Raw QR payload string (not an image); null when there is no valid code right now
    • expires_atinteger | nullrequired
      Expiry of the code (Unix epoch, milliseconds)
    • statusstringrequired
      Session status: pending, qr_ready, connected, disconnected or failed
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
  • 410The device is already connected (error: Already connected)
Request
curl "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/qr" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/qr', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.get(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/qr",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/qr', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "qr": "string",
  "expires_at": 1767225600000,
  "status": "active"
}

Get the WhatsApp profile of a device

GET/v1/sessions/{sessionId}/profile

Returns the linked account: number, display name, picture, About text and, for Business accounts, the business profile and catalog. A connected device is queried live with a 10-second limit, and parts that do not answer in time come back null or empty (syncing: true marks a timed-out lookup). A device that is not connected returns the cached values with connected: false.

Path parameters

  • sessionIdstringrequired
    Session (device) id

Responses

  • 200Profile
    Response fields
    • connectedbooleanrequired
    • syncingboolean
      true when the live lookup timed out and only partial data is returned
    • phone_numberstring | nullrequired
      Digits with country code, no +
    • wa_namestring | nullrequired
    • profile_pic_urlstring | nullrequired
    • aboutstring | nullrequired
      The About / status text
    • is_businessbooleanrequired
    • business_profileobject | nullrequired
      Only for Business accounts
    • business_profile.descriptionstring | nullrequired
    • business_profile.categorystring | nullrequired
    • business_profile.emailstring | nullrequired
    • business_profile.websitearray of anyrequired
    • business_profile.addressstring | nullrequired
    • business_profile.business_hoursarray of objectrequired
    • business_profile.business_hours[].daystringrequired
    • business_profile.business_hours[].modestringrequired
    • business_profile.business_hours[].openstring | nullrequired
      HH:MM
    • business_profile.business_hours[].closestring | nullrequired
      HH:MM
    • catalogarray of objectrequired
      Visible catalog products (Business accounts only; empty otherwise)
    • catalog[].idstringrequired
    • catalog[].namestringrequired
    • catalog[].pricenumberrequired
    • catalog[].currencystringrequired
    • catalog[].descriptionstringrequired
    • catalog[].imagestring | nullrequired
    • catalog[].urlstring | nullrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/profile" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/profile', {
  method: 'GET',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.get(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/profile",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('GET', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/profile', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "connected": true,
  "syncing": true,
  "phone_number": "+447700900123",
  "wa_name": "string",
  "profile_pic_url": "https://example.com/file.jpg",
  "about": "string",
  "is_business": true,
  "business_profile": {
    "description": "Short description",
    "category": "string",
    "email": "[email protected]",
    "website": [
      "string"
    ],
    "address": "string",
    "business_hours": [
      {
        "day": "string",
        "mode": "string",
        "open": "string",
        "close": "string"
      }
    ]
  },
  "catalog": [
    {
      "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "name": "Example",
      "price": 150000,
      "currency": "IDR",
      "description": "Short description",
      "image": "string",
      "url": "https://example.com/file.jpg"
    }
  ]
}

Request a phone-number pairing code

POST/v1/sessions/{sessionId}/pairing-code

Links the device with a code instead of a QR scan: enter the returned code on the phone (WhatsApp, Linked devices, Link with phone number). Needs a session that has a live connection manager, so create it with POST /v1/sessions or call /reconnect first.

Path parameters

  • sessionIdstringrequired
    Session (device) id

Request body

  • phone_numberstringrequired
    Number of the WhatsApp account to link, with country code. Everything but digits is stripped; local-format numbers are not resolved

Responses

  • 200Pairing code
    Response fields
    • codestringrequired
      Code to type on the phone
  • 400phone_number is missing
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions, or the operation is not available to CS-agent logins
  • 404No live connection manager for this session; unknown session, or a session of another tenant
  • 500The library could not create a code; error carries its message
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/pairing-code" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "phone_number": "+447700900123"
}'
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/pairing-code', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "phone_number": "+447700900123"
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.post(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/pairing-code",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "phone_number": "+447700900123",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/pairing-code', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'phone_number' => '+447700900123',
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "code": "RECIPIENT_OPTED_OUT"
}

Reconnect a device

POST/v1/sessions/{sessionId}/reconnect

Restarts the WhatsApp connection of the session. With clear_creds: true the stored credentials are wiped first and the status goes back to pending, so the device has to be linked again (QR or pairing code); this flag only takes effect when the session already has a live connection manager. Poll GET /v1/sessions/{id} for the resulting status.

Path parameters

  • sessionIdstringrequired
    Session (device) id

Request body

  • clear_credsboolean
    Wipe the stored WhatsApp credentials before reconnecting (default false)

Responses

  • 200Reconnect started
    Response fields
    • okbooleanrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions, or the operation is not available to CS-agent logins
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/reconnect" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "clear_creds": true
}'
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/reconnect', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "clear_creds": true
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.post(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/reconnect",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "clear_creds": True,
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/reconnect', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'clear_creds' => true,
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "ok": true
}

Resync groups and chats

POST/v1/sessions/{sessionId}/sync

Re-fetches the participating groups and the WhatsApp app-state (chats, contacts) and refreshes group names in the inbox; waits up to 15 seconds for the app-state part. contacts counts the one-to-one chats known in the inbox, not an address book.

Path parameters

  • sessionIdstringrequired
    Session (device) id

Responses

  • 200Sync finished
    Response fields
    • groupsintegerrequired
      Groups the account participates in
    • contactsintegerrequired
      Distinct one-to-one chats in the inbox
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
  • 409The session is not connected (NOT_CONNECTED)
  • 502The sync failed (SYNC_FAILED)
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/sync" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/sync', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
  },
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.post(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/sync",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/sync', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "groups": 1,
  "contacts": 1
}

Check numbers on WhatsApp

POST/v1/sessions/{sessionId}/validate

Checks which of up to 1 000 numbers or JIDs have a WhatsApp account. Targets are normalised like recipients elsewhere (international format, or local format resolved against the business country or country_code); targets that cannot be normalised are dropped. If the lookup itself fails, every target is reported in not_registered. Limited to 10 calls per minute per key.

Path parameters

  • sessionIdstringrequired
    Session (device) id

Request body

  • targetsarray of stringrequired
    Phone numbers or JIDs
    Up to 1 000 items
  • country_codestring
    Calling code (digits) used for local-format numbers; defaults to the business country

Responses

  • 200Result
    Response fields
    • registeredarray of stringrequired
      JIDs that have a WhatsApp account
    • not_registeredarray of stringrequired
      Normalised JIDs that were not found
  • 400targets is not an array of strings, or has more than 1 000 entries
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
  • 409The session is not connected
  • 429Strict rate limit exceeded: 10 requests per minute (RATE_LIMITED)
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/validate" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "targets": [
    "+447700900123",
    "+12025550123"
  ]
}'
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/validate', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "targets": [
      "+447700900123",
      "+12025550123"
    ]
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.post(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/validate",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "targets": [
            "+447700900123",
            "+12025550123",
        ],
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('POST', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/validate', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'targets' => [
            '+447700900123',
            '+12025550123',
        ],
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "registered": [
    "string"
  ],
  "not_registered": [
    "string"
  ]
}