/ Payouts v1 Dashboard ↗

Environments

Two environments, one base URL, one integration. Which environment you are in is decided by the key you send — nothing else changes, so the code you test is the code that runs.

Base URL#

code
https://api.avvio.xyz/business/api/v1

Every path in this documentation is relative to it.

Environments#

Sandbox Production
Key prefix akid_test_… akid_live_…
Base URL _the same_ _the same_
Organization id in the path _the same_ _the same_
Money Simulated Real
Settlement Seconds Hours to days, per corridor
Rates Fixed and repeatable Live, and they move between quoting and sending

There is no separate hostname to configure and no environment flag to pass. A test key addresses the same organization id as your live key and resolves, server-side, to that organization's sandbox. Which means the only difference between your staging deployment and your production one is the value of two environment variables:

bash
export AVVIO_API_KEY=akid_test_…                     # or akid_live_…
export AVVIO_PRIVATE_KEY="$(cat avvio-sandbox.pem)" # the matching private half

The environment is derived from the prefix you present, never from stored state — so a key that reads akid_test_ in your logs cannot move real money, whatever else is true.

Your sandbox pair and your live pair are different pairs. Generate each in the dashboard when you issue that key; we only ever receive the public half.

What sandbox actually does#

Sandbox runs the real API — the same validation, the same corridor rules, the same error types, the same webhooks. What it does not do is touch a payment network:

Production access#

Production keys are issued once your organization is verified. Nothing about the integration changes at that point: same base URL, same paths, same payloads. You swap two environment variables and the money becomes real — which is why the pre-production checklist is worth an hour before you do.

Versioning#

The version is in the path: v1.

Backwards-compatible changes ship continuously, without a version change. Treat all of these as expected, and build so they cannot break you:

Parse responses permissively: ignore fields you do not recognize, and never enumerate an error type in a way that throws on an unfamiliar one. Every error carries the two facts you need regardless of whether you know its name — whether your money moved, and whether retrying is safe. Errors is the table.

Breaking changes get a new version in the path. Removing a field, renaming one, changing a type, or making an optional parameter required will never happen to v1 in place.

Deprecation#

If we ever retire a version:

We will not shorten a window for a live partner. If a security issue ever forced a faster change, you would hear from a human first, not from a 400.

Rate limits#

Ask before you build against an assumed ceiling — limits vary by route and partner traffic is bucketed per credential, with a separate source-IP abuse ceiling. We would rather raise yours than have you discover it in production. RATE_LIMITED is always safe to retry after the response's backoff interval.