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
Forwhatsapp_inbound, the response includes a verification block with the data your UI needs:
verification.wa_number— the OTP.ID WhatsApp number the user must messageverification.message— the exact text the user must sendverification.wa_link— a deep link that opens WhatsApp with the message pre-filledverification.expires_at— when the inbound verification link and message stop being valid
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.

