POST /otp/send
POST /otp/send
Section titled “POST /otp/send”Issues a six-digit OTP and sends it to a WhatsApp number. The code is never returned.
| Scope | otp |
| Auth | Authorization: Bearer mk_live_… |
| Content-Type | application/json (required) |
| Body limit | 8192 bytes |
| Idempotency | Required — Idempotency-Key, 1–128 characters |
Request
Section titled “Request”| Field | Type | Required | Validation |
|---|---|---|---|
phone |
string | yes | Non-blank. Separators space . - ( ) are stripped, then /^\+[1-9]\d{6,14}$/ |
purpose |
string | yes | login, signup, payment, passwordReset, phoneChange |
curl -X POST https://app.maukirim.com/api/v1/otp/send \ -H "Authorization: Bearer mk_live_…" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: signup-8821" \ -d '{ "phone": "+6281234567890", "purpose": "signup" }'Response
Section titled “Response”200
{ "ok": true, "challengeId": "otp_…", "batchId": "gwb_…", "expiresAt": "2026-09-28T13:20:00.000Z" }| Field | Meaning |
|---|---|
challengeId |
The handle for verification. Store it against your own session. |
batchId |
The dispatch attempt, for support and the dashboard’s message log. |
expiresAt |
Issue time + 5 minutes. |
Errors
Section titled “Errors”| HTTP | Code | Condition |
|---|---|---|
| 400 | invalid_input |
Missing/wrong Content-Type; body over 8192 bytes or not an object; phone missing or not E.164; purpose missing or not in the enum; Idempotency-Key missing or longer than 128 |
| 401 | api_key_invalid / api_key_revoked / api_key_expired |
See Authentication |
| 403 | api_key_scope_denied |
The key lacks otp |
| 403 | forbidden |
The account is missing or not active |
| 402 | insufficient_credits |
Balance below the cost (0 inside the plan allowance, else the plan’s overage rate, else 165) |
| 404 | not_found |
No account row for the key owner |
| 409 | batch_idempotency_conflict |
The key was reused with a different (phone, purpose) |
| 409 | device_not_connected |
No ready MauKirim sending number |
| 413 | batch_too_large |
Submission key over 128 characters |
| 429 | rate_limited |
More than 5 issues per hour for this account and phone number |
| 503 | worker_offline |
The dispatch worker has no fresh heartbeat |
| 500 | server_error |
Unexpected |
- A replay with the same key and the same
(phone, purpose)returns the originalchallengeIdandexpiresAt; no second message is sent and no second charge is made. - The idempotency check runs before template and credit checks, so a replay answers even if the balance later changed.