curl. By the end, you’ll have made real API calls and understand the shape of every response you’ll encounter in production.
The OTP code itself is never returned in API responses — it’s delivered directly to the user through the chosen channel.
1
Get your API key
Every request to the OTP.ID API must include a Bearer API key. To obtain yours:
- Log in to your dashboard at https://app.otp.id.
- Open the Akun (Account) page and find the API Key card.
- Click Tampilkan (Show), confirm with your account password, then copy the key — you’ll pass it in the
Authorizationheader of every request.
550e8400-e29b-41d4-a716-446655440000Keep it secret. Never commit it to source control or expose it in client-side code.2
Send an OTP via WhatsApp
Call A successful response looks like this:Save the
POST /v3/request to have OTP.ID generate a code and deliver it to your user over WhatsApp. Pass destination as the user’s phone number in E.164 format (digits only, no + prefix) and a brand name that will appear in the message.otp_id — you’ll need it in the next two steps. The expires_at field tells you when the code stops being valid. price is the number of credits deducted for this send, and last_balance is your remaining credits after this send.3
Verify the OTP
Once your user submits the code they received, call Successful verification — the code matches:Code mismatch — the user entered the wrong code:
POST /v3/verify with the otp_id from the previous step and the code the user entered.A mismatch returns HTTP
200 with verified: false — it is a valid, expected outcome, not an API error. Only check data.verified to decide whether to grant access.reason is only ever "" (success) or "mismatch" (wrong code). Other outcomes — expired OTP, attempt limit reached, or an already-verified OTP — come back as HTTP 422 error responses with codes OTP_EXPIRED, TOO_MANY_ATTEMPTS, and ALREADY_USED. See the verify reference.4
Check transaction status
For polling-based flows — or when you want to inspect a past OTP record — call The response includes the full OTP record with its current The
GET /v3/otp/{otp_id} with the OTP’s ID.status:status values are pending, sent, success, failed, and verified. For real-time notifications without polling, set up the otp.verified webhook instead.Next Steps
You’ve completed the full OTP flow. Here’s where to go deeper:- Authentication — understand API key scoping and how to handle auth errors.
- Channels — learn when to use SMS, Email, Missed Call, or WhatsApp Inbound instead of WhatsApp outbound.
- Webhooks — set up the
otp.verifiedevent to receive async verification results. - API Reference — see the full schema for every request and response field.

