Integration Guides
Complete common WABA integration tasks in the correct order.
Send Your First WhatsApp Message
- Complete Meta onboarding in the Notify Africa Portal.
- Wait until the Portal reports the connection as ready.
- Create an API key with WABA access.
- Configure a developer webhook in the Portal.
- Subscribe to
message.status.updated. - Choose an approved template.
- Send
POST /v1/waba-api/messages/template. - Store each returned
messageId. - Treat
success: trueas queued, not delivered. - Match later callbacks by
data.messageIdordata.wamid.
curl --request POST \
"$NOTIFY_API_BASE_URL/v1/waba-api/messages/template" \
--header "Authorization: Bearer $NOTIFY_WABA_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"to": "255700000001",
"template_name": "hello_customer",
"language": "en",
"idempotency_key": "welcome-customer-42"
}'Use freeform text only after receiving a customer message and while the 24-hour service window remains open.
Create and Use a Template
- Build a valid
componentSchema. - Declare send-time variables in
variableSchemawhen using binding validation/preview. - Call
POST /v1/waba-api/templateswithchannel: "whatsapp". - Save the returned Notify Africa
templateId. - Poll the template status or process
template.status.updated. - Use sync when the stored projection needs a provider refresh.
- Wait for
approved. - Send using
whatsappConfig.externalTemplateNameastemplate_name. - Match
template_parametersto the approved component order.
Do not look for a submit endpoint. Create performs provider submission. Validate checks bindings; it does not submit or run provider review.
Receive Delivery Events
- Create an HTTPS receiver.
- Preserve the exact raw request bytes.
- Configure the receiver and subscriptions in the Portal.
- Store the one-time signing secret.
- Queue a test delivery from the Portal.
- Build
<timestamp>.<raw-body>. - Calculate HMAC-SHA256 with the webhook secret.
- compare the result with
x-notify-webhook-signatureusing a constant-time function. - reject stale timestamps.
- insert
eventIdunder a unique database constraint. - apply side effects once.
- return 2xx after durable acceptance.
Use the Portal to inspect pending, retrying, failed, discarded, and delivered attempts.
Setup Versus API Usage
| Task | Portal | Developer API |
|---|---|---|
| Meta onboarding | yes | no |
| Select WABA/phone number | yes | no |
| Check connection readiness | yes | no |
| Create/revoke API key | yes | no |
| Configure webhook URL/events | yes | no |
| Rotate webhook secret | yes | no |
| Inspect webhook attempts | yes | no |
| Queue webhook test | yes | no |
| Create/manage templates | no | yes |
| Send messages | no | yes |
Do not automate Portal management actions by copying internal browser requests. Only the documented API-key operations are supported for developer integrations.
Common Integration Mistakes
Wrong authentication
Incorrect: sending a key without the Bearer scheme or using an API key that lacks WABA access.
Correct:
Authorization: Bearer ntfy_your_api_keyWrong identifier
Use the Notify Africa templateId UUID in template paths. Use the external template name in message sends. Do not substitute the Meta template ID for either value.
Unapproved template
Do not treat pending as sendable. Provider preflight runs asynchronously and can fail a request that was initially queued.
Invalid recipient format
The facade trims and deduplicates exact strings but does not normalize phone numbers. Choose one international format and use it consistently.
Wrong template variables
Match the approved template's component and parameter order. Numeric object keys are sorted numerically. The Developer API does not convert a media URL into a media-header object.
Text outside the service window
Use an approved template when the customer has not sent a qualifying inbound message during the preceding 24 hours.
Treating queue acceptance as delivery
The initial message result can be processing without a provider wamid. Use message.status.updated for later state.
Recomputing the signed body
Verify the exact raw bytes received. Parsing and reserializing JSON can change the bytes and invalidate the HMAC.
Processing duplicate events
At-least-once delivery permits duplicates. Enforce a unique constraint on eventId before applying side effects.
Assuming event order
Retries can reorder callbacks. Compare event time and current domain state before applying a transition.
Retrying permanent webhook failures
Notify Africa retries only network errors, timeouts, selected conflict/throttle statuses, and server errors. Other non-2xx responses are discarded. Use the Portal to diagnose them.
