Messaging

Send OTP

Send a WhatsApp verification code with stricter OTP validation and rate limits.

When to use OTP

Use the OTP endpoint when the message contains a short verification code and should be subject to OTP-specific limits. The request can provide a code, or the backend can generate one.

OTP messages are still queued messages. Store the returned `message_id` if your application needs to trace delivery status later.

`code` is optional everywhere. If your application sends it, it must be 4 to 10 digits. If omitted, the API generates the code and returns it as `otp_code`.

Response includes the code

The current API response includes `otp_code` so your backend can verify the user-entered code. Keep that value server-side.

Endpoint reference

The endpoint requires a connected sender and an API key with the `otp` role.

POST/api/otp/send

Generate or send a caller-provided OTP code.

ParameterTypeDescription
x-api-keyrequiredheaderAPI key with the `otp` role.
sender_idrequireduuidConnected sender assigned to the API key.
receiver_numberrequiredstringDestination phone number.
codestringOptional 4-10 digit code. If omitted, the server generates one.
app_namestringApplication name shown in the OTP message, max 80 characters.
ttl_minutesintegerPositive integer up to 60.Default: 10
templatestringOptional custom template, max 512 characters.
idempotency_keystringDuplicate protection key, max 160 characters.
Request
json
{
  "sender_id": "9f4b5d4c-0000-4000-9000-123456789abc",
  "receiver_number": "212612345678",
  "app_name": "My Store",
  "ttl_minutes": 10,
  "source_system": "login",
  "source_reference": "user_123"
}
201 response
json
{
  "message_id": "6d92aa83-8fb4-40f8-8ef2-83c2b8f0319f",
  "status": "queued",
  "duplicate": false,
  "otp_code": "482913",
  "expires_in_minutes": 10
}

Generated vs application codes

Use backend-generated OTP when you want HookMessage to create the code and return it to your server. Store `otp_code` in your own verification attempt record and compare it with the user-entered value.

Use application-generated OTP when your auth system already creates and stores codes. Pass that code in the request and still keep the returned `message_id` for delivery tracing.

Application-generated code
json
{
  "sender_id": "9f4b5d4c-0000-4000-9000-123456789abc",
  "receiver_number": "212612345678",
  "code": "482913",
  "app_name": "My Store",
  "ttl_minutes": 10,
  "source_system": "login",
  "source_reference": "attempt_123"
}

Node.js example

Keep the API key in the server environment and return only your own application result to the browser.

server route
ts
const response = await fetch(`${process.env.HOOKMESSAGE_BASE_URL}/api/otp/send`, {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-api-key": process.env.HOOKMESSAGE_OTP_KEY!,
  },
  body: JSON.stringify({
    sender_id: process.env.HOOKMESSAGE_SENDER_ID,
    receiver_number: phoneNumber,
    app_name: "My Store",
    ttl_minutes: 10,
  }),
});

if (!response.ok) {
  throw new Error("Could not send verification code");
}

const data = await response.json();

Need help?

Use Book Integration Help if you want setup help for OTP or automated customer messaging.

Next steps