Common Issues
Authentication
401 Unauthorized on every request
Symptoms: Every API call returns 401 Unauthorized.
Causes and fixes:
-
Missing header — Ensure you're sending both required headers:
Authorization: Bearer sk_live_yourkey X-Tenant-Id: your-tenant-id -
Wrong key prefix — Operator keys start with
afo_. Customer API keys start withsk_live_. Using the wrong one for the wrong API returns 401. -
Key revoked — Check Settings → API Keys to confirm the key is active. If revoked, create a new key.
-
Key bound to cancelled subscription — Customer API keys are automatically revoked when their subscription is cancelled. The customer must re-subscribe to get a new key.
403 Forbidden — Insufficient permissions
Your API key is valid but doesn't have permission for the action:
- MEMBER role cannot create/modify resources — use ADMIN or OWNER credentials
- BILLING_ADMIN role cannot access product catalog endpoints
- Check the endpoint's required role in the API Reference
API Requests
404 Not Found on an endpoint that exists
Symptoms: A request to a documented endpoint returns 404 Not Found, and the response detail literally contains a {...} token — for example:
{ "status": 404, "detail": "Product not found: {id}", "instance": "/api/v1/products/%7Bid%7D" }
Cause: The path still contains an unsubstituted placeholder. Endpoint paths in the reference use {id}, {customerId}, and similar tokens as placeholders — you have to replace each one with a real value before sending. Sent literally, {id} becomes part of the URL (%7Bid%7D once encoded) and matches nothing.
Fix: Substitute every {param} in the path with an actual identifier:
# Wrong — the placeholder is sent verbatim
curl https://catalog.aforo.ai/api/v1/products/{id} \
-H "Authorization: Bearer sk_live_yourkey" -H "X-Tenant-Id: your-tenant-id"
# Correct
curl https://catalog.aforo.ai/api/v1/products/prod_a1b2c3 \
-H "Authorization: Bearer sk_live_yourkey" -H "X-Tenant-Id: your-tenant-id"
If the detail echoes a real id you supplied (no braces) and you still get 404, the resource genuinely doesn't exist for your tenant — verify the id and that your X-Tenant-Id matches the tenant that owns it.
Usage Ingestion
Events not appearing in the Event Log
Check these in order:
-
Verify the endpoint — Ingest to
https://usage-ingestor.aforo.ai/v1/ingest/events, not any other service URL. -
Validate the payload — Required fields:
{ "customerId": "required", "metricId": "required — must match an active billable unit", "quantity": 1, "timestamp": "2026-04-17T10:00:00Z" } -
Check timestamp — Events more than 90 days old are rejected with
400 Bad Request. Events more than 5 minutes in the future are rejected for clock skew. -
Run diagnostics — Use the Developer Hub's Integration Diagnosis tool:
GET /v1/ingest/diagnose
Events rejected with "metric not found"
The metricId in your event payload doesn't match any active billable unit in your catalog. Check Catalog → Billable Units for the correct ID format.
Late arrival warnings
Events with timestamps 24+ hours in the past are flagged as late arrivals but still processed. If you're seeing many late arrival warnings, check your server clock and ensure NTP is configured correctly.
Billing & Invoices
Customer not receiving invoices
- Check the customer's email address in Commercial → Customers
- Verify your email provider is configured in Settings → Finance
- Check the billing event log for
invoice.send_failedevents - Try manually resending:
POST /api/v1/invoices/{id}/send
Invoice amount looks wrong
- Check the rate plan version pinned to the subscription — pricing changes don't apply to existing subscriptions
- Verify the billing pipeline stage breakdown in the invoice's Usage Attribution tab
- Check for applied credit notes that reduced the total
- Confirm the billing period matches expectations
Bill run partially failed
Some customers succeeded and others failed in the same bill run:
- Open the bill run detail to see per-customer results
- Failed items show error codes — common causes:
WALLET_INSUFFICIENT_FUNDS— Prepaid customer has insufficient balanceUSAGE_DATA_UNAVAILABLE— the usage store was temporarily unavailable; re-run the bill runTAX_CALCULATION_FAILED— Avalara/Vertex timeout; retry the specific invoice
Subscriptions
Subscription stuck in PAST_DUE
Payment has failed and dunning is in progress:
- Check dunning attempt count:
GET /api/v1/subscriptions/{id} - Manually retry payment:
POST /api/v1/subscriptions/{id}/retry-payment - If payment method is outdated, direct customer to update it in the portal
- After resolving payment, subscription auto-moves to ACTIVE on next dunning cycle
Cannot cancel a TRIALING subscription
TRIALING subscriptions can be cancelled. If you're getting an error:
- Ensure you're calling
DELETE /api/v1/subscriptions/{id}(not/cancel) - Check for
CANCELLEDstate — it might already be cancelled
Migration fails with 409 Conflict
Common causes:
- Source subscription is already
CANCELLEDorEXPIRED— terminal states cannot be migrated - Target offering is the same as the current offering — use upgrade/downgrade endpoints instead
- A bulk migration is already in progress for this tenant — wait for it to complete
Gateway Connectivity
Integration shows ERROR status
- Go to Governance → Integrations → [your integration]
- Click Test Connection to get a specific error message
- Common fixes:
- Kong: PAT token expired — generate a new token in Kong Manager
- AWS: IAM role permissions insufficient — check the CloudFormation template was applied
- Azure: Service principal secret expired — rotate in Azure AD
- Apigee: OAuth token expired — re-authorize the integration
Products showing STALE at gateway
The gateway product config has drifted from Aforo's record:
- Click the product → Restore to Gateway
- Review the diff (what Aforo would push to the gateway)
- Confirm the restore
If the restore fails, the gateway may have additional config (plugins, routes) that need to be manually aligned.
SDK Issues
@aforo/metering — events buffering but not sending
Events are buffered and flush every 5 seconds or when 100 events accumulate. If they're not sending:
- Call
await aforo.flush()explicitly before process exit - Check network connectivity to
usage-ingestor.aforo.ai - Verify the API key has ingestion permissions
aforo-metering (Python) — async context errors
If you're seeing RuntimeError: no running event loop:
# Wrong — calling async method in sync context
aforo.ingest(...)
# Correct — use sync wrapper or await in async context
import asyncio
asyncio.run(aforo.ingest(...))
# or in async function:
await aforo.ingest(...)
Need more help?
If you can't find an answer here, contact support and include:
- The request ID from the error response (
X-Request-Idheader) - Your tenant ID
- The exact error message and HTTP status code
- Steps to reproduce