Authentication
Every Swappr API request is authenticated with a Bearer token issued from your dashboard.
API key format
sk_<env>_<32-char-secret>env—test(sandbox) orlive(production)- The first 12 characters (
sk_test_xxxxorsk_live_xxxx) are the visible prefix; the rest is the secret.
The host is the same for both environments (api.swappr.me); we route to sandbox or live based on the key’s env prefix. Resources are env-isolated — a sandbox key can only see sandbox wallets, payouts, beneficiaries, etc. Trying to fetch a live resource id with a sandbox key returns 404, not 401.
Sending the token
Include the key in the Authorization header:
curl https://api.swappr.me/api/v1/payouts \
-H "Authorization: Bearer sk_test_..."IP allowlist
Every API key requires at least one IP address in its allowlist. Requests from any other IP are rejected with 403 ip_not_allowed.
Add IPs from your dashboard:
- API & Webhooks → click the key row → Restrict IPs
- Supports IPv4 and IPv6 (including
::shorthand) - Multiple IPs allowed; comma-separated entry
Production traffic should originate from a fixed egress IP. If you’re hosted on Vercel / Cloudflare Workers / etc. with rotating IPs, route outbound calls through a static-egress proxy (Cloudflare Workers can do this with a static IP plan, or run a small proxy server on AWS/Hetzner with an Elastic IP).
Permissions
API keys inherit permissions from the Owner that created them. Most keys can:
- Read all wallets, payouts, beneficiaries, reports
- Create payouts (single + bulk)
- Manage beneficiaries
- Manage webhook endpoints
Some endpoints require explicit permission grants:
- Additional permissions may apply to capabilities enabled on your account beyond standard B2B disbursement (Owner-only by default)
If a key lacks a required permission, the response is 403 permission_denied.
Rotating keys
Generate a new key from your dashboard, deploy it to your application, then revoke the old key. There’s no automatic grace window — old keys stop working immediately when revoked.
To roll the secret on the same key (rare; usually you create a new one), use Rotate. The rotated secret is shown once + the old secret keeps working for 60 minutes so you can deploy without downtime.
Key expiration
Live keys carry a mandatory expiry, chosen when you create the key: 30, 90, 180, or 365 days. Sandbox keys never expire.
- Expiry is immutable. Once a key is created you can’t change its expiry date.
- Rotating a live key always assigns a fresh duration measured from the moment of rotation — it never extends or inherits the old key’s expiry date. A key you rotate the day before it expires is fully re-armed for its chosen duration, so rotation can’t be used to postpone the deadline indefinitely.
- You’ll be reminded at T-14 days, T-7 days, T-3 days, T-12 hours, and T-2 hours before a key expires, so you can rotate or generate a replacement in time.
- Once a key expires, every request with it returns
401 key_expiredwith a message stating the exact expiry timestamp. Generate a new key from the API Keys page in your dashboard (or rotate before the date arrives).
Revoking keys
From the dashboard, click Revoke on the key. All subsequent requests with that key will return 401 invalid_api_key.
Test vs. live
The sandbox environment uses simulated providers — payouts complete instantly with success/failure outcomes you control via the outcome field. No real money moves.
Live environment uses real upstream rails. Funds debit your wallet and dispatch to the recipient’s bank.
| Feature | Sandbox | Live |
|---|---|---|
| Real money | ❌ No | ✅ Yes |
| KYC required | ❌ No | ✅ Yes |
| NUBAN resolve | ✅ Yes (single configured resolver) | ✅ Yes (capability-first cascade) |
| Webhook delivery | ✅ Yes | ✅ Yes |
| Rate limits | ✅ Same as live | ✅ Same as sandbox |
Use sandbox to integrate + test your error handling, then flip to live keys for production.
Errors
| Code | HTTP | Cause |
|---|---|---|
missing_api_key | 401 | No Authorization header |
invalid_api_key | 401 | Key revoked, malformed, or doesn’t exist |
key_expired | 401 | Live key has passed its expiry date — rotate or generate a new one |
ip_not_allowed | 403 | Request IP not in key’s allowlist |
merchant_suspended | 403 | Your merchant account is suspended (contact support) |
permission_denied | 403 | Key lacks the required permission for this endpoint |