Skip to main content
Use this guide when you want the user to start verification from WhatsApp instead of receiving a code. This channel uses the public alias whatsapp_inbound, and you create it with POST /v3/request only. POST /v3/send does not support this channel. The flow is simple: you create a pending transaction, OTP.ID returns a WhatsApp number plus a pre-filled message, and the user taps the deep link or sends the message manually. OTP.ID matches the inbound message automatically and marks the transaction verified.

How the flow works

1

Create the request

Call POST /v3/request with channel: "whatsapp_inbound". You can omit number for an unbound flow, or include it to bind verification to one sender number.
2

Show the WhatsApp action

Render verification.wa_link as the primary action, or show verification.wa_number and verification.message together if you want the user to copy the text manually.
3

Keep the prompt visible before expiry

Show the deep link and message until verification.expires_at. After that time, disable the action and ask the user to start a new request.
4

OTP.ID matches the inbound message

When the user sends the exact message to verification.wa_number, OTP.ID matches it automatically. If you bound the request with number, OTP.ID only accepts the matching sender number.
5

Update the UI state

Treat the transaction as pending, invalid, expired, or success based on the current status from GET /v3/otp/{otp_id} or the otp.verified webhook.

What the response gives you

For whatsapp_inbound, the response includes a verification block with the data your UI needs:
  • verification.wa_number — the OTP.ID WhatsApp number the user must message
  • verification.message — the exact text the user must send
  • verification.wa_link — a deep link that opens WhatsApp with the message pre-filled
  • verification.expires_at — when the inbound verification link and message stop being valid
Show the deep link and message before verification.expires_at. If the user changes the text, sends from the wrong number on a bound request, or waits too long, the transaction stays unverified and your UI should move back to a fresh request.

UI states to handle