> ## 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.

# Trading integration

> Step-by-step walkthrough to let your users buy, sell and swap crypto with the CaaS API, using reusable quotes.

Your users buy, sell and swap crypto through **reusable quotes**: you create a quote for a pair, which holds a rate for a short window, and then execute it for a specific end user and amount. For request and response details, follow the endpoint link in each step.

## Two kinds of trades

| | Buy / Sell | Swap |
| - | - | - |
| **What it does** | Exchanges crypto against the account's fiat currency (e.g. `BTC_USD`) | Exchanges one crypto for another (e.g. `USDT_ETH`) |
| **Quote** | [Create Reusable Quote](/crypto-as-a-service/reusable-quotes/create-reusable-quote.md): one buy rate and one sell rate | [Create Swap Reusable Quote](/crypto-as-a-service/swap-reusable-quotes/create-swap-reusable-quotes.md): one swap rate |
| **Execution** | You choose `op_type` (`BUY` or `SELL`) and the amount in crypto **or** in fiat | You send the amount of the base asset to swap |
| **Pairs** | Non-swap pairs only | Swap pairs only |

Both share the same setup.

## Common setup

**1. Authenticate**

Get an access token with the OAuth2 Client Credentials flow using your `client_id` and `client_secret`, and send it as a `Bearer` token on every subsequent call. Trading needs the `read` and `write` scopes.

→ [Get Access Token](/crypto-as-a-service/access-token/get-access-token.md)

**2. Create the end user**

Register each of your users with an `external_ref`: your own identifier for them. It must be unique within your account and can only contain letters, digits, `_` and `-`.

Every later call refers to the user by this `external_ref` — it is the `end_user_id` in paths and bodies.

→ [Create End User](/crypto-as-a-service/end-user/create-end-user.md)

**3. Verify the user's identity**

Submit the user's KYC data. What happens next depends on your company — see [Identity verification (KYC)](/crypto-as-a-service/kyc/overview.md). An end user whose KYC is pending or rejected cannot trade: the execution answers `20030`.

**4. Pick a pair**

List the pairs enabled for your account and pass the pair's `name` (e.g. `BTC_USD`) when you create a quote. To show indicative prices before quoting, use the market rates.

→ [Get Account Pairs](/crypto-as-a-service/pairs/get-account-pairs.md) · [Get Last Market Rates](/crypto-as-a-service/rates/get-last-market-rates.md)

> [!NOTE]
>
> Market rates are indicative and change with the amount. The only price you can execute at is the one held by a quote.

## Buy and sell

**1. Create a reusable quote**

Send the `pair` and an `external_ref`. The quote holds both a `buy_rate` and a `sell_rate` (fees included) and is valid for **30 seconds** (`expires_at`). It is not tied to an end user or an amount, so you can execute it for several users while it is valid.

→ [Create Reusable Quote](/crypto-as-a-service/reusable-quotes/create-reusable-quote.md)

**2. Execute it for an end user**

Send the `end_user_id`, the `op_type` (`BUY` or `SELL`), an `external_ref` for this trade, and **exactly one** of:

* `base_amount` — the amount of crypto (e.g. buy 0.01 BTC), or
* `quote_amount` — the amount of fiat (e.g. buy BTC for 100 USD).

```json Request theme={null}
{
    "end_user_id": "CUST-ABC-1",
    "op_type": "BUY",
    "quote_amount": 100,
    "external_ref": "trade-0001"
}
```

The response is the executed trade: `rate`, `charged_fee`, `base_amount`, `quote_amount` and the `txn_id` of the transaction it created.

→ [Execute Reusable Quote](/crypto-as-a-service/reusable-quote-execution/execute-reusable-quote.md)

> [!TIP]
>
> Use a unique `external_ref` per trade. If a request times out, retrying with the same `external_ref` returns the trade that was already executed instead of creating a second one.

## Swap

**1. Create a swap reusable quote**

Send a swap `pair` (e.g. `USDT_ETH`) and an `external_ref`. The quote holds a `swap_rate` and is valid for **30 seconds**.

→ [Create Swap Reusable Quote](/crypto-as-a-service/swap-reusable-quotes/create-swap-reusable-quotes.md)

**2. Execute it for an end user**

Send the `end_user_id`, an `external_ref` and the `base_amount` to swap. There is no `op_type`: the swap debits the base asset and credits the quote asset.

→ [Execute Swap Reusable Quote](/crypto-as-a-service/swap-reusable-quote-execution/execute-swap-reusable-quote.md)

## Following up

* **Transaction status:** every execution creates a transaction. Retrieve it with the `txn_id` from the response, or list them filtered by `end_user`, `op_type` or date. → [Retrieve Transaction](/crypto-as-a-service/transactions/retrieve-transaction.md) · [List Transactions](/crypto-as-a-service/transactions/list-transactions.md)
* **Balances:** → [Get Balances for End User](/crypto-as-a-service/balance/get-balances-for-end-user.md)
* **Limits:** per-transaction minimums and maximums for your account, and the daily, monthly and yearly limits consumed by each user. → [Get Transaction Limits](/crypto-as-a-service/txn-limits/get-transaction-limits.md) · [Get Limits for End User](/crypto-as-a-service/periodic-limits/get-limits-for-end-user.md)

## Common errors

| Code | When | What to do |
| - | - | - |
| `20010` | The quote expired before the execution | Create a new quote and execute it within 30 seconds |
| `20012` | Not enough balance for the operation | Check the user's balance before executing |
| `20021` | The end user is banned | The user cannot operate |
| `20026` | The quote has no price | Create a new quote |
| `20030` | The end user's KYC is not approved | Complete [identity verification](/crypto-as-a-service/kyc/overview.md) first |

Limit errors (frequency, amount, minimums and maximums) and the full list are in [Error handling](/crypto-as-a-service/errors/error-handling.md).

## Testing in sandbox

Use the sandbox base URL (`https://sandbox-b2b.ripio.com`) with your sandbox credentials: the flow and the endpoints are the same as in production. To give an end user balance to sell or swap, fund them first — see [Deposits & withdrawals](/crypto-as-a-service/guides/deposits-and-withdrawals.md) or, for fiat, [Banking as a Service](/crypto-as-a-service/guides/banking-as-a-service.md).


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