Send an OTP message
Deliver your code using an APPROVED AUTHENTICATION template on a sendable WhatsApp sender. Your backend generates and verifies the code.
One accepted send consumes one monthly API OTP unit; later failures are not refunded.
An optional workspace-scoped Idempotency-Key returns the original acceptance body on completed repeats. Repeated requests must match the recipient in international format, Sender ID, template name/language and reference. The code is not compared: changing the code with the same key does not replace the original message.
Unknown query parameters are rejected. Unknown body fields are rejected. All examples use fictional values.
Responses
| Status | Meaning and codes |
|---|---|
| 202 | Accepted. Completion is asynchronous. |
| 401 | Problem Details. Codes: API_KEY_INVALID. |
| 404 | Problem Details. Codes: OTP_SENDER_NOT_FOUND, OTP_TEMPLATE_NOT_FOUND. |
| 409 | Problem Details. Codes: OTP_SENDER_UNAVAILABLE, OTP_TEMPLATE_NOT_USABLE, IDEMPOTENCY_KEY_REUSED. |
| 422 | Problem Details. Codes: DEVELOPER_INVALID_INPUT, RECIPIENT_BLOCKED. |
| 429 | Problem Details. Codes: RATE_LIMITED, OTP_QUOTA_EXCEEDED. Retry-After: 1 is present only for RATE_LIMITED; quota errors do not include it. |
Success and handled error responses send Cache-Control: no-store and X-Correlation-ID (the resolved/generated UUID). Errors use application/problem+json and the reusable ProblemDetails schema below. Retry-After: 1 is sent only for RATE_LIMITED. Request examples read your key from a server environment variable; replace all fictional values.
Schemas and examples
ApiKeyAuthorizationBearer <token>Server-side API key. publicId is 12 lowercase base32 characters (a-z, 2-7); secret is 43 base64url characters from 32 random bytes. Use Authorization: Bearer <complete key>. The API key determines the workspace; requests cannot select another workspace. All public routes share 20 requests per second per key. See API-key authentication.
Idempotency-Key?stringOptional string of at most 128 characters. Empty string is accepted by validation; use a unique non-empty value per request. Save it and reuse it if you are unsure whether the request succeeded. See each operation for which values must match on repeated requests.
length <= 128X-Correlation-ID?stringOptional tracing ID. A UUID-shaped value is echoed in the response. Missing or invalid values are replaced with a generated UUID, not rejected.
application/json- body
to*stringMust be a valid phone number in international format with a leading +; it is normalized to E.164. Surrounding whitespace is trimmed.
1 <= lengthsenderId*stringThe Sender ID of a WhatsApp phone number in your workspace, shown in the dashboard under Developers > Overview (Senders) - not a Meta phone number ID.
uuidtemplate*code*stringCustomer-generated code. Watification delivers it; your backend verifies it.
^[A-Za-z0-9]{1,15}$1 <= length <= 15reference?stringOptional caller reference. Empty string is accepted.
length <= 128Accepted. Completion is asynchronous.
application/json- response
messageId*stringMessage ID to use when checking delivery status.
uuidstatus*stringAcceptance reports queued, including completed idempotent repeats.
reference*|Caller reference, or null if omitted.