Skip to content
Core Concepts

Polling list endpoints

Integrators that poll GET /v1/{phone_number_id}/conversations on a fixed interval do not need to change their request shape — Kirimdev applies three layers of efficiency on the server and in the HTTP contract.

List responses are cached in Redis for 8 seconds per unique query (org, account, filters, cursor, limit, and updated_since). Repeated polls inside that window are served from cache instead of re-running the heavy inbox join.

The cache is invalidated immediately when a conversation row on that account changes (inbound message, outbound send, assignment, status patch, and similar writes).

Pass an ISO 8601 timestamp to fetch only conversations whose updated_at is strictly after that instant:

GET /v1/106540352242922/conversations?updated_since=2026-06-19T10:00:00.000Z&limit=25
Authorization: Bearer kdv_live_...

When nothing changed, the response is a normal 200 with data: []. Store the newest updated_at from each non-empty page and send it on the next poll.

Sort order: requests with updated_since order by updated_at DESC (most recently mutated first). Requests without it keep the inbox order last_message_at DESC. Cursors are only valid for the same query shape — do not reuse a cursor across modes.

Works alongside cursor pagination and the usual status / contact_id filters.

Every list response includes a weak ETag derived from the newest updated_at, max unread_count, row count, and whether another page exists:

HTTP/1.1 200 OK
ETag: W/"2026-06-19T11:00:00.000Z:2:1"

On the next poll, send the value back:

GET /v1/106540352242922/conversations
If-None-Match: W/"2026-06-19T11:00:00.000Z:2:1"

When nothing changed, Kirimdev responds 304 Not Modified with no JSON body — saving bandwidth and client parse time. Rate-limit headers are still attached.

Combine updated_since (smaller DB result sets) with If-None-Match (cheap unchanged responses) for the lowest overhead polling loop.

Message status polling (GET /messages/{id})

Section titled “Message status polling (GET /messages/{id})”

Integrators that poll a single message by msg_* id to watch delivery status get the same server-side protections without changing their code:

StatusCache TTLWhy
pending, sent5 sStatus changes quickly
delivered10 sOne step from terminal
read, failed60 sTerminal — pollers often keep checking

The cache key is per (org, account, message id) and is dropped immediately when the worker applies a status webhook or send pipeline update.

Responses include a weak ETag derived from status and error fields. Send it as If-None-Match to receive 304 Not Modified when the message has not changed.

For new integrations, prefer a message.status webhook subscription instead of polling — but existing poll loops are safe on the platform.