Skip to main content
This page is your complete reference for every response code, transaction status, error code string, and filter value that the Strails API can return. Use it alongside your server logs to diagnose and fix issues quickly.

Response Codes

Every API response includes a response_code field. The six possible values are:

Transaction Status Lifecycles

Onramp requests go through the following statuses as a user funds their cNGN wallet via bank transfer:Lifecycle flow:
Virtual account sub-statuses:
Offramp requests burn cNGN on-chain and pay out Naira to a Nigerian bank account:Lifecycle flow:
FX trades execute against the Strails orderbook and have a strict 5-minute lock window:Lifecycle flow:
A trade can only expire from locked or signing states. Once the transaction reaches settling, it either completes or fails - it cannot expire.
Auto-swaps are triggered after a successful onramp when autoSwap is enabled:
Fee withdrawals convert accumulated platform fees to Naira and send them to your registered bank account:

Common Error Codes

These error code strings appear in the error field of a failed response and indicate the specific reason for the failure:

Common Issues

401 Unauthorized means the API key itself is invalid or missing.
  • Confirm you are sending the header as x-api-key (all lowercase). Sending X-Api-Key or any other casing will result in a 401.
  • Verify you are using the correct key for the environment (sandbox vs. production).
  • Ensure the API key has not been revoked in your dashboard.
403 Forbidden means the key is valid but the request is blocked.
  • Check that the IP address of your server is on your allowlist. Use POST /manageipallowlist with "action": "add" to add it.
  • If you recently added an IP, allow up to 60 seconds for the change to propagate across all servers.
You have exceeded the rate limit for the endpoint.
  • Implement exponential backoff: wait 1 s, then 2 s, then 4 s, etc., before retrying.
  • Queue non-urgent requests client-side and dispatch them at a steady rate rather than in bursts.
  • Cache responses where the underlying data does not change frequently (e.g. supported bank lists).
  • See Rate Limits for per-endpoint limits. A 429 response carries a data.retry_after value in seconds - wait at least that long before retrying.
BVN verification will fail if any of the following are true:
  • The BVN is not exactly 11 numeric digits. Whitespace, hyphens, or other characters cause an immediate VALIDATION_ERROR.
  • The BVN is already registered to another Strails user.
  • The identity provider could not resolve the BVN, or is temporarily unreachable (response_code: "05").
Correct the mismatch and submit a fresh /onboarduser request. You cannot retry the same onboarding record after a failed status - create a new one.
A transaction that stays in pending or processing for more than a few minutes may need intervention:
  1. Call the relevant status endpoint (e.g. /cngnofframpstatus, /onboardstatus) with the requestId to get the latest status and any error detail.
  2. If the status has not changed after 10 minutes, call POST /manualstatusrecovery with the requestId. This endpoint triggers a manual reconciliation check on the backend.
  3. If the transaction is still stuck after a manual recovery attempt, contact support@strails.co with the requestId and timestamp.
Check the following if your webhook endpoint is not receiving events:
  • Your webhook URL must use HTTPS. Plain HTTP endpoints are rejected.
  • Verify the URL you registered via /setwebhook is publicly reachable from the internet. Test it with webhook.site or ngrok http 3000 during local development.
  • Confirm your endpoint returns HTTP 200 within 10 seconds. Slow responses or non-200 status codes cause Strails to retry delivery with backoff.
  • Re-check your webhook signature verification logic. A bug that raises an unhandled exception before the 200 response is sent will cause the delivery to be marked as failed.
  • Inspect your server logs for any incoming POST requests that may have been silently rejected by a firewall or middleware.
Virtual accounts generated by /cngnonramp are valid for 30 minutes only.
  • If a user does not complete the bank transfer before the expiry time, the virtual account status moves to expired and the onramp status moves to failed.
  • You must create a new onramp request via POST /cngnonramp to generate a fresh virtual account. You cannot reactivate an expired one.
  • Display the expiresAt timestamp from /getvirtualaccount in your UI so users know how long they have.

Filter Values Reference

Use these values when querying list endpoints with the type, status, side, and pair filters. Deposits Payouts Transactions FX Orders FX Trades Asset Withdrawals

Amount Format Reminders

Fee withdrawals are kobo, not Naira - "amount": 50000 on /feewithdrawal withdraws ₦500.00. See Fee Management for the full set.
Full per-endpoint breakdown: Amount Formatting.

If you cannot resolve an issue using this guide, email the Strails support team at support@strails.co with your requestId, the full request payload (redact your API key), and the timestamp of the failed call.