---
title: "How to test an off-ramp's liquidity depth before you commit: a quote-ladder protocol"
seoTitle: "How to test off-ramp liquidity depth: a quote-ladder test"
description: "Quote $500, $5,000, $50,000, and $250,000 at the same moment, three times a day, and compare the rate. The protocol, log table, and pass rule."
date: "2026-09-30"
updated: "2026-09-30"
category: "payments"
author: "BlindPay Team"
howto:
  name: "How to test an off-ramp provider's liquidity depth with a quote ladder"
  steps:
    - name: "Fix every variable except size"
      text: "Pick one corridor, one approved recipient bank account, one network and token, and keep currency_type and cover_fees the same on every request. Only the amount changes between rungs."
    - name: "Fire four quotes at the same moment"
      text: "Request quotes for 500, 5,000, 50,000, and 250,000 USD in parallel, within a few seconds of each other, so every rung sees the same market."
    - name: "Record the rate fields from each response"
      text: "Log the market rate, the rate you get, the fees, the amount received, and the expiry for each rung. On BlindPay these are commercial_quotation, blindpay_quotation, flat_fee, receiver_amount, and expires_at."
    - name: "Compute the depth slope"
      text: "Depth slope in bps = (rate at the smallest rung - rate at the rung) / rate at the smallest rung x 10,000. Use the rate before flat fees so fixed charges do not hide the size effect."
    - name: "Repeat at three times of day on three days"
      text: "Run the ladder at the destination market's morning, during the London and New York overlap, and after the destination market closes, on three business days. Log weekend runs separately."
    - name: "Apply the pass rule"
      text: "A slope of 10 bps or less at the top rung means real depth at that size. Between 10 and 50 bps, split large payouts. Above 50 bps, or no binding quote at the top rung, the inventory runs out early."
faq:
  - q: "How do I test an off-ramp provider's liquidity?"
    a: "Request quotes for the same corridor at four sizes, such as $500, $5,000, $50,000, and $250,000, within the same few seconds. Compare the rate each size gets, before flat fees. Repeat at three times of day on three days. If the rate barely moves with size, the provider has depth; if it falls quickly, its inventory runs out early."
  - q: "What quote sizes should I use to test liquidity depth?"
    a: "Use a ladder that spans a factor of 500: $500 for small payouts, $5,000 for a typical B2B invoice, $50,000 for a payroll batch or treasury move, and $250,000 for a large transfer. Add a rung at your own largest real payout. If your account limits are lower, cap the ladder at the largest payout you will actually send."
  - q: "What is a good rate difference between small and large quotes?"
    a: "As a rule of thumb, 10 basis points or less between the $500 rung and the top rung means the provider fills large sizes from the same inventory. Between 10 and 50 bps is usable if you split large payouts. Above 50 bps, or no binding quote at the top size, the provider is reaching for worse prices as the order grows."
  - q: "Does time of day change stablecoin off-ramp rates?"
    a: "It can. FX trading concentrates in a few centers: the BIS found that dealers in the UK, US, Singapore, and Hong Kong handled 75% of FX trading in April 2025. Local currencies such as BRL or MXN trade most actively in their own market hours. Quotes outside those hours can carry a wider margin, so test morning, midday, and evening."
  - q: "Can I test liquidity depth in a sandbox?"
    a: "Not meaningfully. A sandbox shows that your code handles quotes, expiry, and errors, but its prices do not reflect production inventory. At BlindPay, development instances run on testnets with USDB, BlindPay's test stablecoin. Production quotes move no money until you execute them, so run the depth ladder on production quotes and simply never execute."
---

To test an off-ramp's liquidity depth, request quotes for the same corridor at $500, $5,000, $50,000, and $250,000 within the same few seconds. Repeat at three times of day on three days, and compare the rate each size gets in basis points. A rate that stays flat across sizes means real depth. One that falls fast means inventory runs out early.

Earlier guides on [on/off-ramp liquidity with live quotes](/resources/more/on-off-ramp-liquidity-live-quotes) and [liquidity markets](/resources/more/what-is-a-liquidity-market-cross-border-payments) explain why depth matters and suggest a quick three-size check. This is the full protocol: the top rung, the time-of-day runs, the log, and a pass rule you can hand to a finance team.

**Key takeaways**

- Change only the amount. Same corridor, bank account, network, token, fee setting, and the same few seconds.
- Measure the rate before flat fees. Fixed fees make small payouts look expensive and hide what size does to the rate.
- Depth slope = (rate at $500 - rate at the rung) / rate at $500 x 10,000. Under 10 bps at the top rung is a pass.
- Run three sessions a day on three days. Depth that only exists at midday is not depth for a payout that runs at night.
- A quote window that shrinks as size grows, or a binding quote that turns indicative at the top rung, is a failed test.

## What does liquidity depth mean for an off-ramp?

Liquidity depth is the amount a provider can convert on one corridor before its rate gets worse. Deep inventory fills a $250,000 payout at nearly the same rate as a $500 one. Thin inventory has to reach for worse prices, or a third party with its own markup, as the order grows.

Coverage maps do not show this. A provider can list Brazil and still fill only small tickets well. The quote API is the honest witness, as long as you ask it the same question at different sizes. The terms used below (live quote, depth, spread, basis point) are defined in the [on/off-ramp liquidity glossary](/resources/more/onramp-offramp-liquidity-glossary).

## What do you need before you start?

Four things, set once and kept constant for every run.

- **Production quote access.** A quote moves no money until you execute it. Sandbox prices do not reflect real inventory, and BlindPay development instances run on testnets with USDB. [Sandbox vs production](/resources/more/stablecoin-api-sandbox-vs-production) covers what a sandbox can and cannot tell you.
- **One approved recipient bank account per corridor.** Quotes are priced against a specific destination.
- **A fixed funding leg.** Same `network` and `token` on every request, for example USDC on Polygon. Check pairs against [supported chains](/docs/kb/supported-chains).
- **Limits that cover the top rung.** BlindPay checks per-customer limits on the stablecoin amount: $10,000 per transaction for KYC Standard, $30,000 for KYB Standard, and $50,000 for KYC Enhanced by default, per the [customers reference](/docs/learn/customers). Raise them with a [limit increase](/docs/learn/limit-increase), or cap the ladder at your largest real payout. A rung above a limit can come back as an error; log it as a limit, not as thin liquidity.

## What sizes should you test?

Four rungs, spanning a factor of 500, plus your own largest payout if it falls outside them.

| Rung | Amount | What it tells you |
| --- | --- | --- |
| 1 | $500 | Baseline rate. Flat fees dominate the all-in cost here |
| 2 | $5,000 | A typical supplier invoice or contractor payment |
| 3 | $50,000 | A payroll batch or a weekly treasury move |
| 4 | $250,000 | A large transfer. Thin inventory usually breaks here |

The fourth rung is the one most evaluations skip, and it is where providers that route to a partner at quote time show their seams.

## How do you run the quote ladder?

Fire all four quotes in parallel so they see the same market, then save the responses. With BlindPay's [payout quote endpoint](/docs/payout-quotes), `request_amount` is in minor units, so $500 is `50000`.

```bash
# Same corridor, same moment, four sizes. Quotes are never executed.
for amount in 50000 500000 5000000 25000000; do
  curl -s "https://api.blindpay.com/v1/instances/$INSTANCE_ID/quotes" \
    -H "Authorization: Bearer $BLINDPAY_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"bank_account_id\":\"$BANK_ACCOUNT_ID\",\"currency_type\":\"sender\",\"cover_fees\":false,\"request_amount\":$amount,\"network\":\"polygon\",\"token\":\"USDC\"}" \
    > "quote_$amount.json" &
done
wait
```

Then compute the spread and the depth slope for each rung.

```python
import json

base = None
for amount in [50000, 500000, 5000000, 25000000]:
    q = json.load(open(f"quote_{amount}.json"))
    rate, market = q["blindpay_quotation"], q["commercial_quotation"]
    base = base or rate
    spread_bps = (market - rate) / market * 10_000
    slope_bps = (base - rate) / base * 10_000
    print(amount / 100, market, rate, round(spread_bps, 1), round(slope_bps, 1), q["expires_at"])
```

Two columns matter. `commercial_quotation` across rungs shows whether the market price itself moves with size. `blindpay_quotation` is the rate you actually get before flat fees. Keep `flat_fee` in the log, but leave it out of the depth calculation.

## How do you read the results?

Compare the rate at each rung with the rate at $500. The change, in basis points, is the depth slope.

**Illustrative example.** Two providers quote USDC to BRL at the same moment. The market rate is 5.4000 BRL per USDC.

| Rung | Provider A rate | A slope | Provider B rate | B slope |
| --- | --- | --- | --- | --- |
| $500 | 5.3730 | 0 bps | 5.3730 | 0 bps |
| $5,000 | 5.3730 | 0 bps | 5.3720 | 1.9 bps |
| $50,000 | 5.3730 | 0 bps | 5.3460 | 50.3 bps |
| $250,000 | 5.3730 | 0 bps | 5.2920 | 150.8 bps |

Provider B's top rung: (5.3730 - 5.2920) / 5.3730 x 10,000 = 150.8 bps. On $250,000 that is 250,000 x 0.0810 = R$20,250 less for the recipient, about $3,769 at Provider A's rate (20,250 / 5.373). Same corridor, same minute, same quoted "spread" on a small ticket.

## What time of day matters?

The hours when the destination currency trades most. The BIS 2025 Triennial Survey found that sales desks in the UK, US, Singapore, and Hong Kong handled [75% of FX trading in April 2025](https://www.bis.org/press/p250930.htm). Currencies like BRL and MXN also trade heavily in their own onshore hours.

Run each ladder three times a day:

1. **Destination morning**, shortly after the local FX market opens.
2. **London and New York overlap**, roughly 8:00 to 12:00 New York time, when the two largest FX trading centers are both open.
3. **After the destination market closes**, when a provider has to hold risk until the next open.

Do it on three business days. Run any weekend ladder separately and compare it only with other weekend runs: Pix settles 24/7, but the price of reais on a Saturday carries Monday's risk.

## What counts as a pass?

Use the top-rung slope from the worst of your nine runs, not the average. A payout that runs at the worst moment gets the worst rate.

| Worst top-rung slope | Verdict | What to do |
| --- | --- | --- |
| 10 bps or less | Deep at this size | Production-ready for payouts up to the top rung |
| 10 to 50 bps | Usable with care | Split large payouts, or test a middle rung to find where the rate breaks |
| Over 50 bps | Thin | Inventory runs out early. Keep large payouts elsewhere |
| No binding quote | Fail | The provider cannot hold a price at that size |

These thresholds are rules of thumb, not an industry standard. Two more failure signals:

- **The window shrinks with size.** If `expires_at` gets closer as the amount grows, the provider is protecting itself from a book it cannot fill.
- **Last look on the top rung.** The [FX Global Code](https://www.globalfxc.org/fx_global_code.htm) defines last look as a final chance for the quoting firm to accept or reject your request against its quoted price. A large quote that can be rejected after you execute has not passed a depth test, whatever its rate.

One caution on interpretation. The BIS Markets Committee noted that internalised trading [makes liquidity harder to measure from the outside](https://www.bis.org/publ/mktc13.htm). Quote ladders measure what you can get, not what a provider holds, and that is the number your payouts depend on.

## What should you log?

Copy this table into a spreadsheet and fill one row per rung per run.

| Date | Time (UTC) | Corridor | Rung (USD) | commercial_quotation | blindpay_quotation | flat_fee | receiver_amount | Window (s) | Spread (bps) | Slope (bps) | Notes |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| | | | | | | | | | | | |

Window (s) is `expires_at` minus the request time, divided by 1,000, since `expires_at` is in epoch milliseconds. Keep the raw JSON too. When a provider's rates change after you go live, this log is your baseline.

## How does BlindPay show up on this test?

Every BlindPay payout quote returns `commercial_quotation` next to `blindpay_quotation`, itemized fees, and a 5-minute `expires_at`, so the ladder runs on the public API without a sales call. Quotes are funded when you execute them, with no pre-funding. Plans are on the [pricing page](/pricing), and per-transaction fees appear in each quote.

Run the ladder yourself and judge the slope. For who holds the rate while the window is open, see [who carries FX risk in a stablecoin payout](/resources/more/who-carries-fx-risk-stablecoin-payout). For where the inventory behind a quote comes from, see [what a market maker is in stablecoin payments](/resources/more/what-is-a-market-maker-stablecoin-payments). The [slippage guide](/resources/more/stablecoin-fx-slippage-live-quotes) covers the next test after depth: whether the settled rate matches the quoted one. Depth is one row in the full [on/off-ramp provider checklist](/resources/more/how-to-choose-on-off-ramp-provider).

*How we know: BlindPay fields and limits come from the [payout quotes](/docs/payout-quotes) and [customers](/docs/learn/customers) documentation. Market structure figures come from the BIS and the FX Global Code, linked above.*

## What to do next

Pick your largest corridor and run the four-rung ladder once today against the [payout quote endpoint](/docs/payout-quotes). Save the JSON, fill the log, and schedule the other eight runs for the next three days.

*This article is general information, not legal, tax, or financial advice.*
