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

# Off-Ramp integration

> Step-by-step walkthrough to convert crypto into fiat with the Ramps API using a reusable off-ramp session.

Off-Ramp lets your users sell crypto and receive fiat in a bank account. You integrate it with a reusable **off-ramp session**: you set it up once against the customer's destination account, and an off-ramp order is created automatically every time the customer sends crypto to it. For request and response details, follow the endpoint link in each step.

<Note>
  Available payout methods depend on the country. See [Countries & payment methods](/ramps-api/overview/countries/overview) first. In Colombia, Request-to-Pay (R2P) is **On-Ramp only** and cannot be used for payouts.
</Note>

## Common setup

<Steps>
  <Step title="Authenticate">
    Get an access token with the OAuth2 Client Credentials flow and send it as a `Bearer` token on every call.

    → [Acquire Access Token](/ramps-api/authentication/acquire-access-token)
  </Step>

  <Step title="Create the customer">
    Register the end user and keep the returned `customerId`.

    → [Create Customer](/ramps-api/customers/create-customer)
  </Step>

  <Step title="Accept Terms & Conditions">
    Right after creating the customer, register their acceptance of the active Terms & Conditions. This is a required step before the customer can operate.

    It is also a recurring one: acceptance covers the version that was shown, so a new version for the country blocks the customer again until they accept it. Re-check before operating instead of storing the result.

    → [Terms & Conditions](/ramps-api/terms-and-conditions/introduction) · [Accept Terms](/ramps-api/customers/accept-terms)
  </Step>

  <Step title="Verify identity (KYC)">
    The customer must reach KYC status `COMPLETED` before operating.

    → [Identity verification (KYC)](/ramps-api/kyc/overview)
  </Step>

  <Step title="Brazilian accounts: collect the investor profile">
    If your account is in Brazil, your customers must answer a short suitability questionnaire after KYC and before their first order or session, and again every year. Check the status, show the questionnaire when it is `REQUIRED` or `EXPIRED`, and submit the answers; without it, creating an order, a session or a destination account fails with `20100`. Accounts in other countries skip this step, whatever the customer's nationality.

    → [Investor Profile (Brazil)](/ramps-api/investor-profile/introduction)
  </Step>

  <Step title="Register and confirm the payout account">
    Register the user's destination bank account (their **external fiat account**) — for example a CBU/CVU/alias in Argentina, a CLABE in Mexico, a PSE/BRE-B account in Colombia, or a PIX key in Brazil. First fetch the required fields, then create the account and confirm it.

    Validation may be **synchronous** (usable right away) or **asynchronous** (it starts in `processing` and becomes usable once validation returns). It must be `enabled` before it can receive a payout. Keep its `fiatAccountId` — the session needs it.

    <Note>
      In **Brazil (PIX)** the account is a single `pix_key` field and there is no deposit-account prerequisite. The key is resolved to its account holder while the request is served, and the holder's document must match the customer's own CPF/CNPJ — a key belonging to someone else comes back `disabled`. There is no type selector, so each key type must arrive in its canonical format; in particular a **phone key needs the `+` and the country code** (`+5511987654321`). See [PIX key formats](/ramps-api/overview/countries/brazil#pix-key-formats).
    </Note>

    → [Retrieve Fiat Account Requirements](/ramps-api/fiat-accounts/retrieve-fiat-account-requirements) · [Create Fiat Account](/ramps-api/fiat-accounts/create-fiat-account) · [Confirm Fiat Account](/ramps-api/fiat-accounts/confirm-fiat-account) · [Create Deposit Account](/ramps-api/customers/create-deposit-account)
  </Step>
</Steps>

## Set up the off-ramp session

<Steps>
  <Step title="Create the off-ramp session">
    Create a session with the destination `fiatAccountId`. The response includes the **crypto deposit addresses** (one per supported network). The session is reusable and does not expire.

    → [Create Off-Ramp Session](/ramps-api/off-ramp/create-off-ramp-session)
  </Step>

  <Step title="User sends crypto — orders are created automatically">
    Each time the customer sends crypto to a session deposit address, an off-ramp order is created automatically, a fresh quote is applied, the trade executes and the fiat is paid out. No per-deposit API call is needed.

    Track each order with [Off-Ramp Events](/ramps-api/webhooks/off-ramp-events) or by inspecting the session's transactions via [Retrieve an Off-Ramp Session](/ramps-api/off-ramp/retrieve-an-off-ramp-session).
  </Step>
</Steps>

## Order lifecycle

| Status | Meaning |
| - | - |
| `PENDING` | Order created, waiting for the crypto deposit. |
| `PROCESSING` | Deposit detected, trade and payout in progress. |
| `COMPLETED` | Fiat paid out to the destination account. |
| `CANCELLED` | Something went wrong with the order. Most cancellations you can resolve yourself — see below. |
| `REFUNDED` | The amount was refunded to the customer. |

### Resolving a cancelled order

`refundable` on the order tells you which way out it has, and `failureReason` tells you what went wrong:

| `refundable` | What happened | What to do |
| - | - | - |
| `true` | The trade never executed, so the crypto is still there | Return it to the customer — see [Refunds](/ramps-api/refunds/overview). |
| `false` | The crypto was already sold and the **fiat payout** failed — usually `failureReason: INVALID_DESTINATION`, a destination account that cannot receive the money | Retry the payout against another account with [Change Fiat Account and Reprocess](/ramps-api/off-ramp/change-fiat-account). There is nothing to refund. |

The two paths are mutually exclusive: an order is refundable or reprocessable, never both. If neither resolves it, contact Ripio support.

## Payout account states

| State | Meaning |
| - | - |
| `processing` | Validation/registration in progress (async providers). |
| `unconfirmed` | Validated, waiting for confirmation. |
| `enabled` | Confirmed and ready to receive payouts. |
| `suspended` | Was enabled, then deactivated because another account for the same payment method was enabled. Can be reactivated. |
| `disabled` | Validation failed permanently. |

\| `revalidation_required` | The account must be re-validated before it can be used again. |

Only one account can be active per payment method at a time. See [Fiat account lifecycle](/ramps-api/fiat-accounts/lifecycle) for the full state model and how to reactivate a suspended account.


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