Skip to content
Core Concepts

Resource IDs

Every resource exposed through the Public API has a stable, prefixed identifier of the form <prefix>_<26 base32 chars>.

msg_01HXYZABCDEFGHJKMNPQRSTVWX

The one exception is the WhatsApp phone_number_id — that’s Meta’s identifier and uses a different format. See phone_number_id below.

PrefixResource
msg_Message
cnv_Conversation
ctc_Contact
lbl_Label
tmpl_Template
wbs_Webhook subscription
wbd_Webhook delivery
evt_Event (KCKit envelope payload id)
key_API key
sec_Webhook signing secret
req_Request id (response envelope + X-Request-Id header)
org_Organisation
usr_User (conversation assignee)
  • Length: 4 (prefix) + 1 (_) + 26 (id body) = 31 characters total for most resources. tmpl_* is 32 chars (5-char prefix).
  • Alphabet: Crockford base32 (0-9 and A-Z minus I L O U). Always uppercase in the id body.
  • URL-safe: No characters require percent-encoding.
  • Permanent. Once kirim.dev hands you an id, that id refers to that exact resource for as long as the resource exists. Hard deletes remove the row entirely, but the id is never reused for a new row.
  • Opaque. The body of the id encodes no public meaning. Do not parse, decode, or sort by it. Order resources by created_at (always returned alongside).
  • Globally unique within kirim.dev. No two resources share an id, even across organisations.
  • Tenant-scoped retrieval. Every endpoint that takes an id enforces that the resource belongs to the caller’s organisation. A cross-org id returns 404 resource_not_found — never 403, to avoid leaking existence.

The phone_number_id is the WhatsApp Business phone number’s identifier as assigned by Meta. It’s a different beast from kirim.dev’s prefixed ids and appears in every path-scoped endpoint.

GET /v1/106540352242922/messages
POST /v1/106540352242922/messages
GET /v1/106540352242922/messages/msg_01HXYZABCDEFGHJKMNPQRSTVWX
GET /v1/106540352242922/conversations
GET /v1/106540352242922/templates
PropertyValue
FormatDigits only, typically 15–17 characters
IssuerMeta (WhatsApp Business Platform)
StabilityPermanent for the lifetime of the phone number
PositionURL path segment, never request body
DiscoveryGET /v1/accounts exposes it as the phone_number_id field on each connected account
// GET /v1/accounts → 200
{
"data": [
{
"id": "wba_01HXYZABCDEFGHJKMNPQRSTVWX",
"phone_number_id": "106540352242922",
"display_phone_number": "+62 811 1222 333",
"verified_name": "Acme Inc",
"quality_rating": "GREEN",
"status": "approved"
}
],
"has_more": false,
"next_cursor": null
}

Pluck phone_number_id from there and use it as the path segment for every message, conversation, contact, and template operation against that line.

Internally kirim.dev uses 12-character nanoids as primary keys. The public id (msg_…) is stored on a separate column (external_id) and is the only id form ever returned through the API. If you see a shorter id-shaped string somewhere in a payload (e.g. assigned_to on conversations), it’s the internal user id — the only resource without a prefixed external_id contract today.

  • Don’t sort by id. Crockford base32 is lexicographic but the id body is not strictly time-monotonic across all resources. Sort by created_at instead.
  • Don’t substring-match prefixes for routing. Use the resource type implied by the endpoint, not the id prefix on the wire.
  • Don’t store IDs you didn’t get from kirim.dev. Generated ids (yours or anyone else’s) won’t match the storage format and will fail validation with 400 invalid_field_value.
  • Don’t confuse phone_number_id with kirim.dev’s wba_ id. The WhatsApp Business Account row has its own prefixed id, but path-scoped endpoints take Meta’s digit-only phone_number_id. The two travel together in GET /v1/accounts for that reason.
  • Don’t hardcode a phone_number_id in source. Fetch it from /v1/accounts at startup or load it from config. Reconnecting a phone number issues a new id.

List accounts

Discover the phone_number_id for every connected line. API →

Send a message

The most common path-scoped endpoint. API →

Pagination

How created_at-ordered lists page through resources. Read →

Errors

invalid_phone_number_id and resource_not_found envelopes. Read →