Why are on-ramp and off-ramp rates different? Bid, ask, and the round-trip cost

Buying stablecoins and selling them back happen at two prices. How bid, ask, and mid-market rates work, and how to calculate a round-trip cost.

On-ramp and off-ramp rates differ because a provider buys and sells at two prices. The ask, what you pay to get dollars or stablecoins, sits above the mid-market rate. The bid, what you get when you sell them, sits below it. Convert one way and straight back and you pay both gaps plus fees. That total is the round-trip cost.

People notice this the first time they on-ramp R$ 54,000, off-ramp it a minute later, and get back less. Nothing is broken. Two spreads and two sets of fees did exactly what they are built to do. Every term below is defined in the on/off-ramp liquidity glossary.

Key takeaways

  • Every conversion has a side. Buying dollars uses the ask, selling dollars uses the bid.
  • The mid-market rate is a reference point between the two, not a price anyone fills you at.
  • A round trip pays both spreads and both sets of fees. Two 0.5% margins plus small fees come to about 1.13%.
  • Dollars to USDC is not an FX conversion. Its cost is a fee line, not a spread.
  • Measure both legs at the same moment, on the same corridor and size, or the comparison is noise.

What are bid, ask, and mid-market rates?

The bid is the price a dealer pays to buy a currency from you. The ask is the price it charges to sell that currency to you. The mid-market rate sits halfway between them.

Wholesale markets publish both sides. Brazil's central bank releases a daily buy and sell PTAX dollar rate in its open data portal. On September 23, 2026, the buy rate was 5.14080 BRL per USD and the sell rate was 5.14140. That is a gap of 0.0006 reais, about 1.2 basis points around the midpoint.

That is the interbank end of the market, at size, between dealers. Any price you get through an app or an API sits wider, because the provider adds its own margin on each side. The ECB makes the same point about its euro reference rates: they are published for information purposes only, and using them for transactions is strongly discouraged.

Why does a provider quote two different prices?

Because it gets paid in the gap. A provider that fills conversions on demand has to hold inventory in both currencies, hedge the risk of holding it, move money over local rails, and run compliance on every customer.

Four costs end up in the spread:

  1. Inventory risk. Reais held overnight can lose value against the dollar. The provider charges for carrying them.
  2. Hedging. Offsetting that risk in the market has its own cost.
  3. Rails and banking. Local payment systems, bank accounts, and settlement all cost money to run.
  4. Flow imbalance. On many corridors more customers sell dollars than buy them, or the reverse. The provider prices each side to keep inventory balanced, so the two margins are not always equal.

What is a liquidity market explains where that inventory comes from.

Which side of the market does each ramp use?

The direction of the conversion decides the side. This table uses BRL per USD, the way Brazilian rates are usually quoted.

FlowYou areRate you getCompared with mid
On-ramp, BRL to USDCBuying dollars with reaisAskMore reais per USDC than mid
Off-ramp, USDC to BRLSelling dollars for reaisBidFewer reais per USDC than mid
On-ramp, USD to USDCMoving dollars into a dollar stablecoinNo FXFee line only
Off-ramp, USDC to USDMoving a dollar stablecoin into dollarsNo FXFee line only

The last two rows matter. USDC is designed to be redeemable 1:1 for US dollars, so dollars in and USDC out is not a currency exchange. The cost there is a fee, not a spread. Virtual account fees breaks those fees down.

How do you calculate the round-trip cost?

Apply each leg's quoted rate and fees in order, then compare the end amount with the start.

Round-trip cost % = (1 - final amount / starting amount) x 100

Illustrative example. A company on-ramps R$ 54,000 into USDC and off-ramps it straight back. Mid-market is 5.40 BRL per USDC. Each leg carries a 0.5% margin, plus a small flat fee. All numbers are made up for the arithmetic, not BlindPay pricing.

StepRate or feeRunning amount
StartR$ 54,000.00
On-ramp at the ask5.427 BRL per USDC (mid + 0.5%)54,000 / 5.427 = 9,950.25 USDC
On-ramp flat fee10 USDC9,940.25 USDC
Off-ramp at the bid5.373 BRL per USDC (mid - 0.5%)9,940.25 x 5.373 = R$ 53,408.96
Off-ramp flat feeR$ 20R$ 53,388.96
Round-trip costR$ 611.04, or 1.13%

Two margins of 50 basis points each make about 100 basis points. The flat fees add the rest. On a real corridor the two margins may differ, which is why you measure both.

When do businesses pay a round trip without noticing?

More often than you would guess. Three patterns show up again and again.

  • Domestic money through a cross-border pipe. A platform collects reais from Brazilian customers, on-ramps them to USDC, then off-ramps to pay Brazilian sellers. The money never needed to leave the currency, but it paid two spreads.
  • Treasury parked in the wrong currency. A company holds USDC between a BRL receivable and a BRL payable a week later. It pays the round trip, plus a week of FX exposure in each direction.
  • Testing with real money. Teams send small amounts out and back to "check the rails" and then read the loss as a pricing problem.

The fix is the same each time: use stablecoins for the leg that crosses a border, and keep same-currency flows in that currency. Where the exchange rate gets fixed shows which step of each flow sets the rate.

How do you read both sides on a BlindPay quote?

Both quote types show the margin directly. A payin quote returns commercial_quotation, the raw market rate, and blindpay_quotation, the rate including BlindPay's fee. A payout quote returns the same two fields, with blindpay_quotation net of the fee.

To measure one leg:

  1. Read commercial_quotation and blindpay_quotation from the quote.
  2. Margin % = absolute difference / commercial_quotation x 100.
  3. Add the fee lines: flat_fee, partner_fee_amount if your platform adds a markup, and billing_fee_amount if the fee is invoiced at month end.

To measure the round trip, request a payin quote and a payout quote for the same corridor and amount at the same moment, and run the arithmetic from the table above. A quote from this morning and another from this afternoon measures market movement, not spread.

Instance owners and admins can also see the fee schedule per rail and per network, with payin and payout fees listed separately, through the billing fees endpoint. Live quote vs forward vs fixed rate covers what to do when the timing, not the spread, is the risk.

What to do next

Request one payin quote and one payout quote on the same corridor, at the same minute, and compute the round trip from commercial_quotation and blindpay_quotation. The payin quotes docs show the request and every response field.

FAQ