> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stableyard.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Off-ramps

> Pay out local currency from stablecoin to a bank account or a local merchant.

An off-ramp takes stablecoin from an account and delivers local currency to a recipient: a supplier invoice, a contractor payout, a withdrawal to the customer's own bank, or a payment to a local merchant. It is a send payment with a fiat destination.

## Pick the destination

| Destination | `destination.type` |
| - | - |
| A one-time bank beneficiary | `external_bank` |
| A saved, verified beneficiary, including the customer’s own bank | `bank_account` |
| A local merchant, through the market's own payment method | `external_qr` |

Corridors are enabled per market and per app, and the destination types differ by market. Kenya, for example, has local payment methods but no bank rail. [View supported regions and currencies →](/supported-regions-and-currencies)

## Create the payout

Use `POST /v2/payments` with `intent: "send"` and a stable `Idempotency-Key`. `/v2/payments/preview` supports crypto destinations only; it rejects `external_bank`, `bank_account` and `external_qr`. One-time bank and QR routes use a provider quote; the US linked-bank route fixes the crypto input and confirms delivered USD at settlement.

```bash theme={null}
curl -X POST https://staging-api-v2.stableyard.fi/v2/payments \
  -u "$APP_ID:$APP_SECRET" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout:supplier_4471" \
  -d '{
    "intent": "send",
    "sender": { "accountId": "acct_sender" },
    "destination": { "type": "external_bank", "country": "VN", "bankCode": "970436", "accountNumber": "0123456789" },
    "amountMode": "deliver_exact",
    "paymentAmount": { "amount": "100000", "assetType": "fiat", "assetCode": "VND" },
    "externalReference": "supplier_4471"
  }'
```

Creation returns the funding terms and next action; it does not prove collection or payout. Fund a quoted payout within `quoteExpiresAt`. An expired payout quote cannot be refreshed on the same Payment. Read the original Payment and reconcile any funds sent before starting a new attempt with a new key after it is terminal. See [Fund a fiat send before its quote expires](/payments/sending-payments#fund-a-fiat-send-before-its-quote-expires).

## US linked-bank payout

Use a bank already linked under the sending UPA. US one-time `external_bank` payments and receive settlement into a linked bank are not released.

1. Read `GET /v2/partners/config` for the app's bank access and payment permissions.
2. Activate `linked_bank` for the intended US/USD rail and wait for account-level approval from `GET /v2/accounts/{accountId}/capabilities`.
3. Read bank-account requirements, link the beneficiary, and wait until the returned bank is `active` with provider provisioning complete.
4. Configure the sender's supported [Payment Source](/payments/sending-payments#set-a-payment-source-first).
5. Create the Payment using the returned `bankAccountId` and an exact crypto input.

```bash theme={null}
curl -X POST https://prod-api.stableyard.fi/v2/payments \
  -u "$APP_ID:$APP_SECRET" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout:us_bank_485" \
  -d '{
    "intent": "send",
    "sender": { "accountId": "acct_sender" },
    "destination": { "type": "bank_account", "bankAccountId": "bank_123" },
    "amountMode": "collect_exact",
    "paymentAmount": { "amount": "100.00", "assetType": "crypto", "assetCode": "USDC", "chainId": 42161 },
    "externalReference": "us_bank_485"
  }'
```

This production example collects 100 USDC on Arbitrum One. The linked bank determines the payout rail. Fees are deducted from the collected amount; the final USD delivery and conversion cost are confirmed only at settlement, so this does not promise a fixed dollar amount. Preserve the precision returned by the API. See [amount semantics](/payments/sending-payments#create-the-payment).

Complete the returned checkout funding action and follow its selected option's `confirmationMode`. Escrow funding is not submitted through the outgoing `/confirm` endpoint. Reconcile `GET /v2/payments/{paymentId}` and signed `payment.*` events until a terminal outcome, checking `operationalState` separately.

The [coverage page](/supported-regions-and-currencies#us-bank-environments-and-certification) distinguishes implementation support, app enablement and live certification. Sandbox requests use the sandbox base URL, accounts and supported testnet source.

## Link a bank before paying it

Linking needs linked-bank access enabled for your app. An `individual` account needs an approved identity check. A `business` account can link a US dollar bank after hosted KYB, and no other country.

Read `GET /v2/accounts/{accountId}/bank-account-requirements` for the fields and availability, then `POST /v2/accounts/{accountId}/bank-accounts`. A linked bank is not a payout destination until its provider has verified it.

## Business bank access

A `business` account starts hosted verification with a capability activation and a stable `Idempotency-Key`.

```bash theme={null}
curl -X POST https://staging-api-v2.stableyard.fi/v2/accounts/acct_123/capability-activations \
  -u "$APP_ID:$APP_SECRET" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: kyb:acct_123" \
  -d '{
    "capability": "linked_bank",
    "country": "US",
    "currency": "USD",
    "rail": "ach",
    "business": { "legalName": "Example Company Ltd" }
  }'
```

Send `business.legalName` only on the first application, or when replaying that exact request after an interruption. Then act on `nextAction.type`:

| `nextAction.type` | Do this |
| - | - |
| `complete_compliance` | Open `nextAction.url` for the company's authorised representative |
| `continue_business_verification` | Resume the activation to get the existing hosted link back |

<Warning>
  Treat `nextAction.url` as a credential. Never log it, and never keep it in browser storage. An expired business application needs Stableyard support; do not start it again as another customer.
</Warning>

The hosted form collects company, ownership, document and consent details, and banking is enabled only after the provider approves. Read `GET /v2/accounts/{accountId}/capabilities` after verification and wait for `ready: true`.

To fund in US dollars as well, activate `bank_onramp` on the same approved relationship; `business` can be left out once the application exists. Your program, product and rail grants must cover each service.

In the partner dashboard, the same flow is under **Accounts → an account → Banking**: start or resume KYB, set up US dollar funding, reveal bank instructions, and send to verified US linked banks. Link the bank itself under **Settlement** once approved.

<Card title="Next: Transactions" icon="receipt" href="/payments/transactions">
  The ledger rows every payment leg writes.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.