Sign in →

Common Issues

Authentication

401 Unauthorized on every request

Symptoms: Every API call returns 401 Unauthorized.

Causes and fixes:

  1. Missing header — Ensure you're sending both required headers:

    Authorization: Bearer sk_live_yourkey
    X-Tenant-Id: your-tenant-id
    
  2. Sandbox vs live key — Keys are sk_test_… (sandbox) or sk_live_… (production). Sending a sk_test_ key to a production endpoint (or vice-versa) returns 401. Check the prefix matches the environment you're calling.

  3. Key revoked — Check Developer → Developer Hub → Credentials to confirm the key is active. If revoked, create a new key.

  4. 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 in your workspace — verify the id and that your X-Tenant-Id matches the workspace that owns it.


Usage Ingestion

Events not appearing in the Event Log

Check these in order:

  1. Verify the endpoint — Ingest to https://usage-ingestor.aforo.ai/v1/ingest/events, not any other service URL.

  2. Validate the payload — Required fields:

    {
      "customerId": "required",
      "metricName": "required — must match an active billable unit",
      "quantity": 1,
      "occurredAt": "2026-04-17T10:00:00Z"
    }
    
  3. Check the 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.

  4. Run diagnostics — Call the ingestion diagnostics endpoint:

    GET /v1/ingest/diagnose
    

Events rejected with "metric not found"

The metricName in your event payload doesn't match any active billable unit in your catalog. Check Catalog → Billable Units for the exact name.

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

  1. Check the customer's email address in Commercial → Customers
  2. Verify your email provider is configured in Settings → Finance
  3. Check the billing event log for invoice.send_failed events
  4. Try manually resending: POST /api/v1/invoices/{id}/send

Invoice amount looks wrong

  1. Check the rate plan version pinned to the subscription — pricing changes don't apply to existing subscriptions
  2. Verify the billing pipeline stage breakdown in the invoice's Usage Attribution tab
  3. Check for applied credit notes that reduced the total
  4. Confirm the billing period matches expectations

Bill run partially failed

Some customers succeeded and others failed in the same bill run:

  1. Open the bill run detail to see per-customer results
  2. Failed items show error codes — common causes:
    • WALLET_INSUFFICIENT_FUNDS — Prepaid customer has insufficient balance
    • USAGE_DATA_UNAVAILABLE — the usage store was temporarily unavailable; re-run the bill run
    • TAX_CALCULATION_FAILED — Avalara timeout; retry the specific invoice

Subscriptions

Subscription stuck in PAST_DUE

Payment has failed and dunning is in progress:

  1. Check dunning attempt count: GET /api/v1/subscriptions/{id}
  2. Manually retry payment: POST /api/v1/subscriptions/{id}/retry-payment
  3. If payment method is outdated, direct customer to update it in the portal
  4. 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 CANCELLED state — it might already be cancelled

Migration fails with 409 Conflict

Common causes:

  • Source subscription is already CANCELLED or EXPIRED — 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 workspace — wait for it to complete

Gateway Connectivity

Integration shows ERROR status

  1. Go to Governance → Integrations → [your integration]
  2. Click Test Connection to get a specific error message
  3. 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:

  1. Click the product → Restore to Gateway
  2. Review the diff (what Aforo would push to the gateway)
  3. Confirm the restore

If the restore fails, the gateway may have additional config (plugins, routes) that need to be manually aligned.


Storefront & Domains

Subdomain shows taken, or Provision Storefront fails

Symptoms: In Channels → Domain & Routing, the subdomain field shows taken, or Provision Storefront returns a conflict.

Cause: Subdomains and custom domains are unique across all of Aforo — each handle routes to exactly one storefront, so the value you entered is already held by another organization.

Fix: Pick a different subdomain (the field re-checks availability as you type) instead of retrying the same one. Custom domains work the same way — if a hostname is already registered to another organization, choose a different one. See Domain & Routing for the full subdomain and custom-domain lifecycle.


SDK Issues

@aforo/metering — events buffering but not sending

Events are buffered and flush on an interval or once the buffer reaches the flush count (default 50 events). If they're not sending:

  1. Call await aforo.flush() (or aforo.shutdown()) explicitly before process exit
  2. Check network connectivity to the ingest host
  3. 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.track(...)

# Correct — use sync wrapper or await in async context
import asyncio
asyncio.run(aforo.track(...))
# or in async function:
await aforo.track(...)

Need more help?

If you can't find an answer here, contact support and include:

  • The request ID from the error response (X-Request-Id header)
  • Your workspace ID (the X-Tenant-Id value)
  • The exact error message and HTTP status code
  • Steps to reproduce