Skip to content
PaalChat Docs

Build and operate

Idempotency and references

Your IDs make every call safe to repeat.

.md

In a nutshell

Use your own IDs everywhere - external_id for businesses, reference for messages, the delivery ID for callbacks. Repeating a request with the same ID never creates a second business or sends a second message.

Three IDs, three guarantees

ID Where Guarantee
external_id POST /businesses Same ID = same business. Repeating updates it.
reference POST .../messages Same reference for the same business = same message. Repeating returns the original (200) and sends nothing.
X-PaalChat-Delivery Callbacks Same ID = same event. Process it once.
Idempotency-Key header Any write (POST, PUT, PATCH, DELETE) Same key + same request within 24 hours = the first response again, nothing done twice.

The Idempotency-Key header

Any write accepts an Idempotency-Key header - your own unique ID for that request (1-255 printable characters). A retry with the same key and the same body gets the first response back, with Idempotent-Replayed: true, and nothing happens twice.

  • The same key with a different request is refused: 409 idempotency_key_reused.
  • A retry while the first request is still running gets 409 idempotency_in_progress - wait a moment and retry with the same key.
  • Keys are kept for 24 hours, per product and per environment (live and test).
  • Server errors (5xx) and 429 are not kept, so retrying with the same key works.
  • For messages, reference does the same job without a time limit - use both if you like.

References for messages

Use your own database ID for the message, for example notification-4411 or m8812. Rules: 1-191 printable characters, no spaces, unique per business.

Text
First call   POST .../messages  reference=notification-4411  →  202 Accepted (queued)
Retry        POST .../messages  reference=notification-4411  →  200 OK (the same message, not sent again)

Warning

Never generate a new reference for a retry. A new reference is a new message.

Without a reference, every call sends a new message - a retry after a timeout may send it twice. Always send one.

References in callbacks

message.status callbacks carry your reference, so you can update your own row without storing PaalChat's IDs. The platform's message_id and Meta's wamid are included too.

Callbacks can repeat

A callback can arrive more than once (retries, resends) and out of order. Store X-PaalChat-Delivery and skip deliveries you have processed. For messages, also key on wamid and apply statuses only forward.