Skip to content

Going live means a verified business, a funded balance and a live key in place of the test one. Work through the checklist first.

A live key addresses the same organization id and the same endpoints. Only the prefix changes, from avvio_test_… to avvio_live_…. If anything else in your integration has to change, that is a bug on our side; tell us.

export AVVIO_API_KEY=avvio_live_…
Sandbox Live
Settlement Seconds Hours to days, per corridor
Rates Fixed Real, and they move between quoting and sending
Balance sandbox/fund Funded by wire to the account GET .../payin-accounts returns, or with USDC in your wallet
Failure triggers Account-number suffix Whatever actually happens
Corridors A handful What your routing supports. Read the corridors call

We don’t publish settlement time per corridor, so ask us about the corridors you plan to use. Each payout carries expectedSettlementAt whenever the network states a window; read it from GET /orders/{payoutId} and show it instead of a fixed estimate. The sandbox never simulates a real settlement window.

Corridors and their field names follow your routing, and we may re-route you. Build forms from GET /recipients/{orgId}/corridors, never hardcoded names.

GET /payments/organizations/{orgId}/policy
curl -s "$AVVIO_BASE_URL/payments/organizations/$AVVIO_ORG_ID/policy" \
-H "x-api-key: $AVVIO_API_KEY"

The policy is what your organization is bound by, read live from its configuration:

Field Holds
limits USD caps, null for none
approvals thresholdUsd and the approvers a held payout needs
features, rateLimits What is enabled, and requests per minute
idempotency The replay windows
purposeOfPayment Currencies that require a purpose
fees.payout The fee schedule (Fees)

A live organization can differ from its sandbox. Read it again with the live key rather than discovering a cap from a 422.

  • You store your Idempotency-Key before you send and reuse it on every retry. A new key per attempt is refused for 15 minutes (409 DUPLICATE_REQUEST_DETECTED) and pays twice after that.

  • You treat a timeout as an unknown outcome and retry it with the same key.

  • Your ledger does not treat completed as final (test with suffix 0003).

  • You have run every payout scenario that applies, 0001 to 0007 (Test scenarios).

  • You read fundsReturned instead of inferring it from failureCode. Absent means unknown, not false.

  • You reconcile from GET /events, sending nextSince back as since, and dedupe on id (Reconcile your ledger).

    curl -s "$AVVIO_BASE_URL/payments/organizations/$AVVIO_ORG_ID/events?since=624" \
    -H "x-api-key: $AVVIO_API_KEY"

    [!WARNING] Unknown query parameters are ignored, so ?nextSince= replays your whole history on every poll.

    Don’t drive your ledger from GET /orders?updatedSince=: updatedAt moves whenever a payout does, so rows land behind a cursor you already passed.

  • Your webhook receiver (Receive and verify webhooks) verifies signatures over the raw bytes and rejects a wrong secret (tested), accepts either signature during a rotation, dedupes on svix-id, ignores events older than the state you hold, returns 2xx before its own work, and is reachable over public HTTPS.

  • You still reconcile against GET /events on a schedule: a webhook you never received looks exactly like one that never fired.

If you accept payments, also confirm:

  • Fulfillment runs from checkout_payment.paid, not the redirect, joined on clientReferenceId with amount and currency checked against your record.
  • The endpoint names the checkout_payment.* types; an empty events list receives none of them.
  • You handle a decline (.01, .05, with differing failureCodes), a full refund (.03), a chargeback after booking (.04), and a partial refund (.06: checkout_payment.partially_refunded, status still paid).
  • Business verification (KYB) is complete. Live keys are issued only after it, so start it first.
  • Every corridor you need appears in GET /recipients/{orgId}/corridors for your organization.
  • Your balance is funded by wire or USDC; there is no live sandbox/fund. Wire lead time depends on both banks, so confirm it with your Avvio contact and fund ahead of your first run.
  • A person has registered your live webhook endpoint in the dashboard and stored its secret. An API key cannot create, change or delete live endpoints, so a leaked key cannot redirect your notifications; it can still read them and their deliveries.
  • You log requestId. On a success it is only in the x-request-id header, so reading res.body.requestId logs undefined.
  • Someone can review a compliance_rejected payout, whose funds do not come back automatically.
  • Your compliance team has read the written screening delegation. Sanctions and name screening of recipients is delegated to the network that executes the payout, and we hold the letter. Destination-country screening is ours and answers 422 PAYOUT_REFUSED; give someone a place to see those.
  • With approvals on, you treat a 202 pending_approval from POST /payouts or batch confirm as held, and wait for payout_approval.executed for the payoutId.

Limits match the sandbox (Environments & sandbox). Back off by the 429’s Retry-After.

Tell us before a big run (“5,000 payouts on Friday”). Corridor limits, balance headroom and rate ceilings can all be raised, but not retroactively.

Was this page helpful?