Troubleshooting Guide
A symptom-driven guide to resolving the most common AfriRoute integration problems. Each section lists likely causes and concrete fixes. When opening a support ticket, always include the request_id from the error response.
๐ Authentication Failures (401 / 403)โ
Symptom: MISSING_API_KEY, INVALID_API_KEY, or FORBIDDEN_SCOPE.
- Confirm the header is exactly
Authorization: Bearer $AFRIROUTE_API_KEYโ notAuthorization, notBearer:. - Verify you are using the correct key for the environment (
$AFRIROUTE_API_KEYfor production,$AFRIROUTE_API_KEYfor sandbox). - Check the key has not been revoked or rotated in the dashboard.
- For
FORBIDDEN_SCOPE, ensure the key's scopes include the product you're calling. - For
IP_NOT_ALLOWED, add your server's egress IP to the key's allowlist.
โฑ๏ธ Rate Limiting (429)โ
Symptom: RATE_LIMIT_EXCEEDED or QUOTA_EXCEEDED.
- Read
X-RateLimit-RemainingandX-RateLimit-Reseton each response to pace requests. - Honor the
Retry-Afterheader before retrying. - Implement exponential backoff (see snippet below).
- If you consistently hit limits, upgrade your plan or request a custom limit.
async function withBackoff(fn, max = 5) {
for (let i = 0; i < max; i++) {
const res = await fn();
if (res.status !== 429) return res;
const wait = (parseInt(res.headers.get('Retry-After')) || 2 ** i) * 1000;
await new Promise((r) => setTimeout(r, wait));
}
throw new Error('rate limit: retries exhausted');
}
๐ต Message Not Deliveredโ
Symptom: SMS shows failed / UNDELIVERABLE.
- Validate the recipient is in E.164 format (
+251911234567, not0911234567). - Confirm the destination country is supported.
- Use a registered sender ID โ unregistered IDs are filtered in many markets.
- Check wallet balance;
INSUFFICIENT_BALANCEsilently blocks sends. - Some networks block promotional content during quiet hours โ schedule within business hours.
๐ฐ Payment Stuck or Failingโ
Symptom: PAYMENT_DECLINED, INSUFFICIENT_FUNDS, or a transaction stuck in pending.
- A
pendingmobile-money charge is normal until the payer approves the prompt; rely on thepayment.completedwebhook, not the synchronous response. - For
DUPLICATE_TRANSACTION, reuse the original reference instead of generating a new one. - For
PROVIDER_UNAVAILABLE, retry after a short delay โ the provider, not AfriRoute, is down.
๐ Webhooks Not Arrivingโ
Symptom: No callbacks reach your server.
- Confirm the endpoint is publicly reachable over HTTPS (test with
curlfrom outside your network). - Verify the webhook is enabled and subscribed to the right events.
- Check the Delivery Log in the dashboard for response codes and bodies.
- Ensure you respond with
2xxwithin 10 seconds, or events are retried then dead-lettered. - Behind a proxy/load balancer? Make sure it forwards the raw body and
X-AfriRoute-Signatureheader.
๐ Signature Verification Failsโ
Symptom: Your handler computes a different signature than X-AfriRoute-Signature.
- Sign the raw request body, not a re-serialized JSON object โ re-serialization changes byte-for-byte content.
- Include the timestamp: HMAC input is
"{t}.{raw_body}". - Use the correct
whsec_...secret for that specific webhook. - Use constant-time comparison. See Webhook Security.
๐ชช Identity Verification Rejectedโ
Symptom: IMAGE_QUALITY_LOW, FACE_MISMATCH, or LIVENESS_FAILED.
IMAGE_QUALITY_LOW: re-capture with even lighting, no glare, the document filling the frame.FACE_MISMATCH: ensure the selfie is frontal and recent; lowermin_confidenceonly if your risk policy allows.LIVENESS_FAILED: confirm a live capture (not a photo of a screen) and that the active challenge matches.REGISTRY_UNAVAILABLE: retry later; government registries have intermittent downtime.
๐งช General Debugging Checklistโ
- Reproduce against the sandbox base URL first.
- Capture the full error envelope including
request_id. - Compare your request to the documented schema field by field.
- Confirm clock sync on your server (NTP) โ skewed clocks break signature timestamps and JWTs.
- Escalate to [email protected] with the
request_idand a minimal repro.
๐ Related Resourcesโ
Last Updated: May 2026 | Need help? [email protected]