BluetickedDeveloper docs

Core concepts

Pagination, idempotency, test mode and versioning: the four rules that apply to every endpoint.

The four rules

These apply to every endpoint, so they are worth reading once rather than discovering one 4xx at a time.

Idempotency

Send an Idempotency-Key header (a UUID) on the POST routes that honour it: messages, campaigns, contacts, templates, flows, events/send, webhooks, integrations, groups, studio flows, flow publish, delivery replay, replay failed, table rows and template submit. On those, a replay within 24 hours returns the original response. Every other POST IGNORES the header, so retrying one after a timeout can create a second record; check the endpoint before you rely on it. Reusing a key with a different body returns 409 idempotency_conflict; a concurrent duplicate returns 409 idempotency_in_progress with retry-after.

Versioning

The API is versioned in the path (/api/v1). Additive changes (new endpoints, new optional fields, new response fields) ship without a version bump, so parse responses leniently and ignore fields you do not recognise. Existing endpoints and fields are not removed or renamed. On the rare occasion a change could fail an existing integration, it is in the changelog marked breaking, in the same deploy, with migration guidance.

Test mode

Blueticked has two independent test tools. Test API keys (blu_test_…) simulate every send end to end: a message row, flagged test_mode, is created and simulated. On a test key a message moves queued → sent → delivered, about one step every 5 seconds, and on to read for WhatsApp; SMS and email stop at delivered. The webhooks message.sent, message.delivered and message.failed fire as it moves; the simulated read fires none. No provider is called, no credits are spent, and nothing touches your WhatsApp quality rating. Each webhook carries "test": true, and +27800000003 also fires a simulated message.received reply; use these to build and run a full integration. test_mode: true (a request field) is a dry run that validates your request and returns status: "validated" without creating or sending anything, and works with any key including a live one. You can combine them, but a test key already sandboxes everything. To rehearse a failure, send the X-Simulate-Error header with a test key and name the code: the response is the real status, code and next_steps (the Errors page lists the codes you can ask for). A test key sandboxes sends, not data: a test key's writes are real, so a contact it creates lives in your workspace beside your customers. A live key refuses to send to the sandbox numbers (+27800000000 to +27800000099) from the send endpoint, but a campaign or a flow does not check the number, so delete test contacts before you go live.

Sandbox recipient numbers and their simulated outcomes
+27800000001Always delivers
+27800000002Fails at send with recipient_unreachable
+27800000003Delivers, then fires a simulated message.received reply