Documentation
Quickstart
Send and verify your first one-time passcode in a few minutes, using a sandbox test key so nothing is charged and no real message is sent.
The flow is two steps: send a code, then verify what the user enters. This guide runs both in the sandbox, so no real message goes out and nothing is charged. When you are ready for production, swap the test key for a live one.
1. Get an API key
Create a key on the API Keys screen in your dashboard.
- A test key (
otp_test_…) runs in the sandbox: no real message, no charge. - A live key (
otp_live_…) sends for real.
Send the key as a Bearer token on every request. See Authentication for details.
2. Send a code
Call POST /otp/send with the recipient (a phone number in E.164 form, or an
email address) and the end user’s IP as client_ip. You do not pass a channel:
your app routing chooses it. The response returns an otp_id you use to track
and verify the code. client_ip is optional on the wire but worth passing from
day one: requests without it share a much tighter rate limit, and it feeds the
abuse protection that guards your own traffic (see send).
curl -X POST https://api.otp.com/api/v1/otp/send \
-H "Authorization: Bearer otp_test_•••" \
-H "Content-Type: application/json" \
-d '{"recipient":"+14155552671","locale":"en","client_ip":"81.2.69.142"}'
{
"otp_id": "9f3c1b2a-…",
"status": "pending",
"channel": "sms",
"masked_recipient": "+1****71",
"action_url": null,
"completion": "code"
}
If routing picks WhatsApp, the response may also carry an action_url (a wa.me
link) the user opens to finish on chat. completion tells you what happens after
that: "code" means they receive a code and you verify exactly as below. The three
WhatsApp shapes are covered in WhatsApp verification.
3. Verify what the user entered
When the user types the code, call POST /otp/verify with the otp_id and the
code. matched: true means the code was correct and the OTP is approved. This is
the same on every channel, WhatsApp included, except when the send came back with
completion: "inbound": that OTP approves without a code (see
WhatsApp verification).
In the sandbox, the accepted code is always 123456.
curl -X POST https://api.otp.com/api/v1/otp/verify \
-H "Authorization: Bearer otp_test_•••" \
-H "Content-Type: application/json" \
-d '{"otp_id":"9f3c1b2a-…","code":"123456"}'
{
"otp_id": "9f3c1b2a-…",
"status": "approved",
"matched": true
}
4. If it did not arrive
Call POST /otp/resend to advance to the next channel in your order (for example
SMS to WhatsApp), or force one with {"channel":"sms"}. GET /otp/{otp_id} reads
the status at any time.
Next steps
- Copy a ready-made snippet in your language from Code examples.
- Understand the lifecycle in How verification works.
- Verifying over WhatsApp? Read WhatsApp verification.
- Read the full API reference.