Errors
Handle authentication, validation, readiness, asynchronous provider, and webhook failures.
Error Envelope
Developer API request errors use:
{
"status": 400,
"message": "Request validation failed",
"code": "VALIDATION_ERROR",
"timestamp": "2026-09-09T11:20:00.000Z",
"path": "/v1/waba-api/templates",
"error": ["name must be longer than or equal to 2 characters"]
}error can be a string, array, or object. details appears when the failure includes structured diagnostics.
Authentication
Required header:
Authorization: Bearer ntfy_your_api_keyRequests fail before business logic when the key is:
- missing.
- malformed.
- revoked or inactive.
- expired.
- not authorized for WABA.
- not accepted by the authentication dependency before timeout.
Request Validation
Correct the request before retrying:
- malformed UUID path parameter.
- missing required field.
- invalid template name or locale.
- invalid component, placeholder, button, or authentication-template shape.
- text longer than 4096 characters.
- idempotency key longer than 128 characters.
- empty recipient set after processing.
- more than 500 recipients.
- invalid pagination or filter values.
Readiness
Template creation requires a ready WABA connection. Message processing requires an owned connection with a selected phone number and usable downstream credentials.
When readiness fails:
- open WhatsApp setup in the Portal.
- review the displayed blocking reasons.
- repair connection, credential, phone-number, or provider-subscription state.
- retry only after the Portal reports ready.
Do not add provider identifiers to the request as a workaround.
Template Conflicts
A duplicate external template name and language for the same owner returns a conflict. Retrieve the existing template and update, synchronize, or delete it instead of creating another copy.
Template Rejection
When status is rejected:
- retrieve the full template.
- inspect
whatsappConfig.providerStatus. - inspect
whatsappConfig.statusInfo.reasonanddetails. - apply the listed corrections.
- update provider fields.
- wait for the resulting
pendingtemplate to be reviewed again.
Unknown provider states are normalized to pending; inspect the raw provider state before deciding what to do.
Closed Service Window
Freeform text outside the open 24-hour window returns a recipient result like:
{
"to": "255700000001",
"success": false,
"error": "Freeform text is not currently permitted for this recipient. Use an approved template send instead."
}Send an approved template to that recipient.
Asynchronous Message Failures
success: true in the HTTP response means queued. Later processing can fail because of:
- disconnected or stale provider credentials.
- missing selected phone number.
- missing/unapproved provider template.
- language mismatch.
- parameter/component mismatch.
- provider rejection or throttling.
Store messageId, wamid when present, recipient, template name, language, and the client idempotency key. Process message.status.updated for final state.
API Retry Policy
| Failure | Client action |
|---|---|
| Validation or invalid identifier | Correct request; do not retry unchanged |
| Authentication | replace/fix credentials; do not retry unchanged |
| Not found | verify tenant ownership and identifier |
| Conflict | retrieve the existing resource or change the natural key |
| Readiness failure | repair setup in the Portal |
| Timeout, dependency unavailable, or server error | retry with exponential backoff and jitter |
Use a stable idempotency_key when retrying a logical message send.
Webhook Failures
Notify Africa retries:
- network errors.
- callback timeouts.
408,409,425, and429.5xx.
Other non-2xx responses are discarded. A callback has a 5-second timeout and retries only within the configured 24-hour window.
Use the Portal to inspect response status, response-body sample, attempt count, next attempt, and error message. Correct the receiver, queue another test, then reactivate a paused endpoint in the Portal.
Signature Failures
Reject a callback when:
- timestamp is absent or outside your replay window.
- signature is absent or malformed.
- HMAC does not match.
- raw body bytes were not preserved.
Verify before JSON parsing. Do not log the webhook secret, API key, or full sensitive payload.
