Idempotency
Send anIdempotency-Key header on start (and on WhatsApp sends) to make retries safe. The key is 1 to 128 printable ASCII characters that you generate, scoped to your API key. Replaying it returns the original 201 unchanged, with the response header Idempotent-Replayed: true; nothing is sent or charged again. A send that fails releases the key so a retry can go through.
Your own reference
reference (up to 64 printable characters) is echoed on start and on GET /v1/verify/{id}, and is searchable in the dashboard’s verifications list. Put your order id or session id there.
Rate limits
The two
429 codes share a status and differ in the error string. The per-key limit fails open if the limiter itself is unavailable.
The protection guard
Three per-application settings stop a runaway integration or an attacker from spending your balance. All are evaluated onstart and resend, and skipped in the sandbox.
- Daily spend cap (
daily_spend_cap_halalas, off by default): today’s charges plus this send would pass the cap, so the send answers429 spend_cap_reached. Days are Riyadh calendar days. - Per-IP cap (
max_per_ip_per_hour, default 20): only checked when you passclient_iponstart. The address is never inferred from the request. Over the cap answers429 ip_rate_limited. - New-destination pumping (
max_new_destinations_per_hour, default 300): crossing it auto-pauses the application. Every call then answers403 application_pauseduntil the owner resumes it from the dashboard. The pause is audit-logged and the owner is notified.
Pass
client_ip whenever the verification is started on behalf of an end user’s request. It is the one signal that lets Tawked tell many users apart from one abuser.Verification lifecycle
resend keeps the id and issues a new code: the old code stops working, attempts and expiry reset, and the send is charged and rate-limited like any other. A new start never invalidates an earlier code. Read the current state at any time with GET /v1/verify/{id} without consuming an attempt.