Errors return a JSON body with a human-readable message and a machine-readable code:
"message" : " to is required " ,
"code" : " VALIDATION_ERROR "
Branch on code, not on message: message wording can change.
Status
code
Cause
Fix
401
UNAUTHORIZED
Missing, wrong, deleted or disabled API key
Send Authorization: Bearer <key> with a live key
403
TEST_MODE_KEY_UNSUPPORTED
Legacy test-mode key
Create a live key in Integrations
POST /v1/{phone_number_id}/messages — see Send a message for
the full table.
Status
code
Cause
Fix
400
VALIDATION_ERROR
Invalid JSON, missing to/type, an unsupported type, the wrong shape for the type’s object, a group recipient, or to missing the + and country code
Fix the request per message
400
TEMPLATE_LANGUAGE_REQUIRED
Template name exists in several languages and none was given
Set template.language.code; available_languages lists the options
403
OUTSIDE_24H_WINDOW
Non-template message outside the 24-hour window
Send a template
403
TEMPLATE_NOT_APPROVED
The named template isn’t APPROVED
Wait for approval, or use a different template
404
ACCOUNT_NOT_FOUND
No number with this phone_number_id in your organization
Check the Accounts page
404
TEMPLATE_NOT_FOUND
No template with this name on the number’s WABA
Create it or sync
404
TEMPLATE_LANGUAGE_NOT_FOUND
The name exists but not in the requested language
Use one of available_languages
409
ACCOUNT_NOT_REGISTERED
The number hasn’t completed phone registration
Finish setup in the dashboard
422
SEND_FAILED
(?sync=true, or mark-as-read) WhatsApp rejected the request. message says why.
Fix the request per message
Returned with status 403 when your plan doesn’t allow a send. The body adds reason, plus
details that depend on the code:
"message" : " message quota exceeded for this subscription period " ,
"code" : " PLAN_QUOTA_EXCEEDED " ,
"meter" : " messages_outbound " ,
"period_end" : " 2026-09-30T23:59:59Z "
code
reason
Extra fields
Meaning
PLAN_NO_ACTIVE_SUBSCRIPTION
no_subscription
Your organization has no active plan
PLAN_EXPIRED
expired
period_end
The plan period has ended
PLAN_QUOTA_EXCEEDED
quota
meter, period_end
You’ve used this period’s message allowance
PLAN_MESSAGE_TYPE_NOT_ALLOWED
message_type
message_type
This message type isn’t in your plan
PLAN_CATEGORY_NOT_ALLOWED
template_category
category, allowed
This template category isn’t in your plan
PLAN_CATEGORY_UNRESOLVED
template_category
The template’s category couldn’t be found; check the template name and language
PLAN_COUNTRY_NOT_ALLOWED
country
country, allowed
Sending to this country isn’t in your plan
PLAN_COUNTRY_UNRESOLVED
country
The recipient’s country couldn’t be worked out from to; include the country code
Status
code
Cause
400
INVALID_ID
The message ID isn’t a valid UUID
404
NOT_FOUND
No such message in your organization
500
FETCH_FAILED
Temporary error. Retry.
/v1/{waba_id}/templates, /v1/{waba_id}/templates/sync, /v1/{waba_id}/templates/bulk and
/v1/templates/{template_id} — see the individual
list , create ,
edit , delete and
sync pages for the full tables.
Status
code
Cause
400
VALIDATION_ERROR
Invalid JSON, or a bad filter/paging value
401
UNAUTHORIZED
Missing, wrong or disabled API key
404
NOT_FOUND
No such WABA or template in your organization
409
ACCOUNT_NOT_REGISTERED
The WABA has no active, registered number
422
META_REJECTED
WhatsApp rejected the request. meta_error carries Meta’s own error detail.
502
META_AUTH_FAILED
WhatsApp rejected Hello’s credentials for this WABA (sync)
502
META_UNAVAILABLE
WhatsApp’s API was unreachable or returned a server error (sync)
500
Temporary server error. Retry.
Status
code
Cause
400
MISSING_PHONE_NUMBER / MISSING_FILENAME / MISSING_CONTENT_TYPE
Required parameter missing
400
MISSING_FILE
No file, or an invalid data URI
400
INVALID_MEDIA
Unsupported type, too large, empty, or contents don’t match the type
404
ACCOUNT_NOT_FOUND
phone_number doesn’t match a connected number
4xx
UPLOAD_REJECTED
WhatsApp rejected the file
502
UPLOAD_REJECTED
WhatsApp rejected Hello’s credentials for this number; contact support
500
UPLOAD_FAILED
Upload failed. Retry.
5xx and network errors are safe to retry with backoff, except on
POST /v1/{phone_number_id}/messages: a retry can send the message twice unless you set an
Idempotency-Key header — a retry with the same key returns the original message instead of
sending again.
Don’t retry 4xx errors unchanged. Fix the request first.