ChatKomodo Docs Home Sign in

API reference · Conversations

Inbox

Conversations: chat lists, messages of a chat, read state, tags, notes, pin, archive and close.

List the chats of a device

GET/v1/sessions/{sessionId}/inbox

List chats with last message, unread count, and group flag.

Path parameters

  • sessionIdstringrequired

Query parameters

  • limitinteger
    Default: 50From 1 to 200
  • offsetinteger | null
    Default: 0

Responses

  • 200Inbox listing
    Response fields
    • inboxarray of objectrequired
    • inbox[].idstringrequired
    • inbox[].session_idstringrequired
    • inbox[].chat_idstringrequired
      Up to 64 characters
    • inbox[].chat_namestring | nullrequired
    • inbox[].last_messagestring | nullrequired
    • inbox[].last_message_atintegerrequired
    • inbox[].unread_countintegerrequired
    • inbox[].is_groupintegerrequired
      1 = group chat, 0 = 1-on-1
    • inbox[].agent_idstring | nullrequired
      Assigned CS agent, or null for unassigned
    • inbox[].statusstringrequired
Request
curl "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox', {
  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/inbox",
    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/inbox', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "inbox": [
    {
      "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "session_id": "YOUR_DEVICE_ID",
      "chat_id": "+447700900123",
      "chat_name": "string",
      "last_message": "Hi Sam, your order has shipped.",
      "last_message_at": 1767225600000,
      "unread_count": 12,
      "is_group": 1,
      "agent_id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "status": "active"
    }
  ]
}

List chats seen in history

GET/v1/sessions/{sessionId}/contacts

Distinct chat ids found in the stored message history of the session, most recently active first (max 100). Derived from the message log, not from the WhatsApp address book.

Path parameters

  • sessionIdstringrequired
    Session (device) id

Responses

  • 200Chats
    Response fields
    • contactsarray of objectrequired
    • contacts[].chat_idstringrequired
    • contacts[].last_seenintegerrequired
      Time of the latest message in the chat (Unix epoch, milliseconds)
  • 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/contacts" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/contacts', {
  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/contacts",
    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/contacts', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "contacts": [
    {
      "chat_id": "+447700900123",
      "last_seen": 1
    }
  ]
}

List the messages of a chat

GET/v1/sessions/{sessionId}/inbox/{chatId}/messages

Messages of one chat, oldest first within the page. Pass next_cursor as before to load older messages. Rows are returned as stored in the message log (more columns than listed may be present).

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Query parameters

  • limitinteger
    Page size; values outside 1-100 are clamped
    Default: 50From 1 to 100
  • beforenumber
    created_at (epoch ms) of the oldest message already loaded; non-numeric values are ignored

Responses

  • 200A page of messages
    Response fields
    • messagesarray of objectrequired
      Oldest first
    • messages[].idstringrequired
      Gateway message id (ULID)
    • messages[].directionstringrequired
      One of: inbound, outbound
    • messages[].chat_idstringrequired
      Chat JID
    • messages[].message_typestringrequired
      text, image, video, document, audio, sticker, location, poll, contact or reaction
    • messages[].bodystring | nullrequired
      Text content, if any
    • messages[].media_r2_keystring | nullrequired
      Key of the stored media file; download it with GET /v1/sessions/{sessionId}/messages/{id}/media
    • messages[].statusstringrequired
      queued, sent, delivered, read, failed, cancelled or deleted
    • messages[].created_atintegerrequired
      Creation time (Unix epoch, milliseconds)
    • messages[].wa_message_idstring | nullrequired
      WhatsApp message id; null until the message was handed to WhatsApp
    • messages[].sent_atinteger | nullrequired
      Time the message was handed to WhatsApp (Unix epoch, milliseconds)
    • messages[].errorstring | nullrequired
      Failure reason of a failed message
    • has_morebooleanrequired
      true when the page is full
    • next_cursorinteger | nullrequired
      created_at of the oldest message in the page (Unix epoch, milliseconds), or null
  • 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/inbox/447700900123%40s.whatsapp.net/messages" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/messages', {
  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/inbox/447700900123%40s.whatsapp.net/messages",
    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/inbox/447700900123%40s.whatsapp.net/messages', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "messages": [
    {
      "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "direction": "inbound",
      "chat_id": "+447700900123",
      "message_type": "Hi Sam, your order has shipped.",
      "body": "Hi Sam, your order has shipped.",
      "media_r2_key": "uploads/abc123.jpg",
      "status": "active",
      "created_at": 1767225600000,
      "wa_message_id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "sent_at": 1767225600000,
      "error": "string"
    }
  ],
  "has_more": true,
  "next_cursor": 1
}

Close a chat

POST/v1/sessions/{sessionId}/inbox/{chatId}/close

Marks the inbox chat closed and resolves its agent assignment. If the tenant enabled the CSAT survey (setting csat_config), the session is connected and the chat is a one-to-one chat, the survey question is sent and a pending response is recorded.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Responses

  • 200Closed
    Response fields
    • okbooleanrequired
    • statusstringrequired
      One of: closed
    • csat_sentbooleanrequired
      true when the CSAT survey was sent
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/close" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/close', {
  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/inbox/447700900123%40s.whatsapp.net/close",
    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/inbox/447700900123%40s.whatsapp.net/close', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

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

Reset the unread counter

POST/v1/sessions/{sessionId}/inbox/{chatId}/read

Sets the unread counter of the inbox chat to zero. This is local only: no read receipt is sent to WhatsApp (see POST …/messages/{msgId}/read). Answers 200 even when the chat is unknown.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Responses

  • 200Reset
    Response fields
    • okbooleanrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/read" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/read', {
  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/inbox/447700900123%40s.whatsapp.net/read",
    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/inbox/447700900123%40s.whatsapp.net/read', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

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

Get tags, notes, pin and archive state

GET/v1/sessions/{sessionId}/inbox/{chatId}/metadata

Returns the organisation data of a chat. A chat without any stored data returns empty tags and notes with pinned and archived false.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Responses

  • 200Chat metadata
    Response fields
    • tagsarray of objectrequired
      Tags attached to the chat
    • tags[].namestringrequired
    • tags[].colorstringrequired
    • notesarray of stringrequired
      Internal notes, newest first
    • pinnedbooleanrequired
    • archivedbooleanrequired
  • 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/inbox/447700900123%40s.whatsapp.net/metadata" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/metadata', {
  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/inbox/447700900123%40s.whatsapp.net/metadata",
    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/inbox/447700900123%40s.whatsapp.net/metadata', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "tags": [
    {
      "name": "Example",
      "color": "#0a7350"
    }
  ],
  "notes": [
    "Prefers delivery after 5 pm"
  ],
  "pinned": true,
  "archived": true
}

Replace tags, notes, pin and archive state

PUT/v1/sessions/{sessionId}/inbox/{chatId}/metadata

Replaces the whole record: fields left out are reset (tags and notes to empty, pinned and archived to false). The body is not validated; use the dedicated tag, note, pin and archive calls to change a single thing.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Request body

  • tagsarray of object
  • tags[].namestringrequired
  • tags[].colorstringrequired
  • notesarray of string
  • pinnedboolean
    Any truthy value pins
  • archivedboolean
    Any truthy value archives

Responses

  • 200Saved
    Response fields
    • okbooleanrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X PUT "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/metadata" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "tags": [
    {
      "name": "VIP",
      "color": "#0a7350"
    }
  ],
  "notes": [
    "Prefers delivery after 5 pm"
  ],
  "pinned": true,
  "archived": false
}'
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/metadata', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "tags": [
      {
        "name": "VIP",
        "color": "#0a7350"
      }
    ],
    "notes": [
      "Prefers delivery after 5 pm"
    ],
    "pinned": true,
    "archived": false
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.code}: ${data.error}`);
console.log(data);
import os
import requests

res = requests.put(
    "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/metadata",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "tags": [
            {
                "name": "VIP",
                "color": "#0a7350",
            },
        ],
        "notes": [
            "Prefers delivery after 5 pm",
        ],
        "pinned": True,
        "archived": False,
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
<?php
require 'vendor/autoload.php';

$client = new GuzzleHttp\Client();
$res = $client->request('PUT', 'https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/metadata', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'tags' => [
            [
                'name' => 'VIP',
                'color' => '#0a7350',
            ],
        ],
        'notes' => [
            'Prefers delivery after 5 pm',
        ],
        'pinned' => true,
        'archived' => false,
    ],
]);

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

Add a tag to a chat

POST/v1/sessions/{sessionId}/inbox/{chatId}/tags

Appends a tag to the chat. The call does not de-duplicate: adding the same name twice stores it twice.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Request body

  • namestringrequired
    Tag name
  • colorstringrequired
    Tag colour, free text such as a hex code

Responses

  • 200Tag added
    Response fields
    • okbooleanrequired
    • tagsarray of objectrequired
      All tags of the chat
    • tags[].namestringrequired
    • tags[].colorstringrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/tags" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "vip",
  "color": "#0a7350"
}'
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/tags', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "vip",
    "color": "#0a7350"
  }),
});
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/inbox/447700900123%40s.whatsapp.net/tags",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "name": "vip",
        "color": "#0a7350",
    },
    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/inbox/447700900123%40s.whatsapp.net/tags', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'name' => 'vip',
        'color' => '#0a7350',
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "ok": true,
  "tags": [
    {
      "name": "vip",
      "color": "#0a7350"
    }
  ]
}

Add a note to a chat

POST/v1/sessions/{sessionId}/inbox/{chatId}/notes

Adds an internal note at the top of the chat notes. Notes are never sent to the contact.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Request body

  • textstringrequired
    Note text

Responses

  • 200Note added
    Response fields
    • okbooleanrequired
    • notesarray of stringrequired
      All notes of the chat, newest first
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/notes" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "text": "Hi Sam, your order has shipped."
}'
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/notes', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "text": "Hi Sam, your order has shipped."
  }),
});
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/inbox/447700900123%40s.whatsapp.net/notes",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "text": "Hi Sam, your order has shipped.",
    },
    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/inbox/447700900123%40s.whatsapp.net/notes', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'text' => 'Hi Sam, your order has shipped.',
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "ok": true,
  "notes": [
    "Prefers delivery after 5 pm"
  ]
}

Toggle the pin of a chat

POST/v1/sessions/{sessionId}/inbox/{chatId}/pin

Flips the pinned flag of the chat (pinned becomes unpinned and the other way round). The response does not return the new state; read it from the metadata.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Responses

  • 200Toggled
    Response fields
    • okbooleanrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/pin" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/pin', {
  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/inbox/447700900123%40s.whatsapp.net/pin",
    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/inbox/447700900123%40s.whatsapp.net/pin', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

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

Toggle the archive flag of a chat

POST/v1/sessions/{sessionId}/inbox/{chatId}/archive

Flips the archived flag of the chat. The response does not return the new state; read it from the metadata.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Responses

  • 200Toggled
    Response fields
    • okbooleanrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/archive" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/archive', {
  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/inbox/447700900123%40s.whatsapp.net/archive",
    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/inbox/447700900123%40s.whatsapp.net/archive', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

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

Set local message expiry for a chat

POST/v1/sessions/{sessionId}/inbox/{chatId}/disappearing

Stores a retention time for the chat. A background job that runs every 5 minutes deletes the messages of the chat older than that time from the stored history. It does not change the disappearing-messages setting of the chat on WhatsApp (for groups see PUT …/groups/{gid}/ephemeral). null or 0 turns it off.

Path parameters

  • sessionIdstringrequired
    Session (device) id
  • chatIdstringrequired
    Chat id (JID) exactly as stored in the inbox, e.g. [email protected] or …@g.us. URL-decoded by the server; no phone-number normalisation is applied

Request body

  • duration_msinteger | nullrequired
    Keep messages this long, in milliseconds; null or 0 disables

Responses

  • 200Saved
    Response fields
    • okbooleanrequired
    • duration_msinteger | nullrequired
  • 401Missing or invalid credentials
  • 403The API key is restricted to other sessions
  • 404Unknown session, or a session of another tenant
Request
curl -X POST "https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/disappearing" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "duration_ms": 604800000
}'
const res = await fetch('https://api.chatkomodo.com/v1/sessions/YOUR_DEVICE_ID/inbox/447700900123%40s.whatsapp.net/disappearing', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHATKOMODO_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "duration_ms": 604800000
  }),
});
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/inbox/447700900123%40s.whatsapp.net/disappearing",
    headers={
        "Authorization": f"Bearer {os.environ['CHATKOMODO_API_KEY']}",
    },
    json={
        "duration_ms": 604800000,
    },
    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/inbox/447700900123%40s.whatsapp.net/disappearing', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
    'json' => [
        'duration_ms' => 604800000,
    ],
]);

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

List chats across all devices

GET/v1/inbox

Chats of all the tenant's devices, most recent first. For an agent login only chats assigned to that agent or unassigned are returned. Per-device listing is GET /v1/sessions/{sessionId}/inbox.

Query parameters

  • limitinteger
    Values outside 1-1 000 are clamped
    Default: 100From 1 to 1 000
  • offsetinteger | null
    Default: 0From 0 to 1 000 000

Responses

  • 200Chats
    Response fields
    • inboxarray of objectrequired
    • inbox[].idstringrequired
    • inbox[].session_idstringrequired
    • inbox[].chat_idstringrequired
    • inbox[].chat_namestring | nullrequired
    • inbox[].last_messagestring | nullrequired
    • inbox[].last_message_atinteger | nullrequired
    • inbox[].unread_countinteger | nullrequired
    • inbox[].is_groupinteger | nullrequired
      1 = group chat, 0 = 1-on-1
    • inbox[].agent_idstring | nullrequired
      Assigned agent, or null
    • inbox[].statusstring | nullrequired
      open or resolved
  • 401Missing, invalid or expired credentials
Request
curl "https://api.chatkomodo.com/v1/inbox" \
  -H "Authorization: Bearer $CHATKOMODO_API_KEY"
const res = await fetch('https://api.chatkomodo.com/v1/inbox', {
  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/inbox",
    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/inbox', [
    'headers' => [
        'Authorization' => 'Bearer ' . getenv('CHATKOMODO_API_KEY'),
    ],
]);

print_r(json_decode((string) $res->getBody(), true));
Response 200
{
  "inbox": [
    {
      "id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "session_id": "YOUR_DEVICE_ID",
      "chat_id": "+447700900123",
      "chat_name": "string",
      "last_message": "Hi Sam, your order has shipped.",
      "last_message_at": 1767225600000,
      "unread_count": 12,
      "is_group": 1,
      "agent_id": "01JA5V6Q8M2H7G4K9P3T0R1S2X",
      "status": "active"
    }
  ]
}