---
title: "Stablecoin FX slippage: how live quotes turn the quoted rate into the rate you get"
seoTitle: "Stablecoin FX slippage and live quotes explained"
description: "FX slippage is the gap between the rate a stablecoin on-ramp or off-ramp shows and the rate that settles. Why quote freshness is a liquidity signal, and how to check a quote-then-execute flow."
date: "2026-09-22"
category: "payments"
author: "BlindPay Team"
faq:
  - q: "What is a live FX quote?"
    a: "A live FX quote is a binding price for a currency conversion, calculated at the moment you request it and held for a stated window. It carries an id and an expiry time. If you execute against it before it expires, the conversion settles at the quoted rate and fees, and the recipient gets the quoted amount."
  - q: "How is a live quote different from a fixed exchange rate?"
    a: "A fixed exchange rate is set by a provider or a government and stays the same until someone changes it, regardless of the market. A live quote follows the market: each request returns a fresh rate, locked for a few minutes. Fixed rates are simpler to display, but the provider protects itself with a wider spread, so you pay for that stability either way."
  - q: "Why does quote freshness matter for stablecoin payouts?"
    a: "Because the older the rate, the more the market has moved since it was calculated, and someone absorbs that move. With a live, binding quote, the provider absorbs it inside the window. With a stale or indicative rate, the gap lands on you or your recipient as slippage, and it only shows up after the payout settles."
  - q: "What is FX slippage in a stablecoin payment?"
    a: "FX slippage is the difference between the exchange rate you were shown and the rate at which your conversion actually settled. It happens when a provider displays an indicative or cached rate and executes later at the market. Unlike a spread, which is a known cost in the quote, slippage is a cost you did not agree to."
  - q: "How do you calculate FX slippage?"
    a: "Subtract the settled rate from the quoted rate, divide by the quoted rate, and multiply by 10,000 to get basis points. If you were quoted 5.40 reais per USDC and the conversion settled at 5.37, slippage is about 56 basis points. On a binding live quote executed inside its window, slippage should be zero."
---

An on-ramp converts fiat money into stablecoins: dollars in a bank account become USDC in a wallet. An off-ramp does the reverse: USDC or USDT becomes local currency in a bank account, over a rail like Pix or SPEI. Every on-ramp and off-ramp payment has an exchange rate, and FX slippage is the gap between the rate you were shown and the rate that actually settled.

A live quote is how a provider closes that gap. How fresh the quote is, and whether it is binding, tells you more about a provider's liquidity than any coverage map.

## What is FX slippage in a stablecoin payment?

FX slippage is the difference between the quoted exchange rate and the settled exchange rate. It shows up when a provider displays one rate, executes the conversion later, and settles at whatever the market says at that later moment.

The formula is short:

`slippage (bps) = (quoted rate - settled rate) / quoted rate x 10,000`

An illustrative example. An app shows a user 5.40 reais per USDC on a 10,000 USDC off-ramp, so the screen says 54,000 reais. The provider executes a minute later at 5.37. The recipient gets 53,700 reais. That is 300 reais missing, about 56 basis points of slippage, and nobody agreed to it.

Slippage can run in your favor too. It doesn't matter. A cost that moves randomly is still a cost you can't price, reconcile, or promise to a customer.

## What is the difference between a live, indicative, and stale quote?

| Quote type | What it is | Is it binding? | Who carries the rate risk |
| --- | --- | --- | --- |
| Live quote | Calculated at request time, with an id and an expiry | Yes, inside the window | The provider, until expiry |
| Indicative quote | An estimate based on a recent market rate | No; execution happens later at market | You, or your recipient |
| Stale quote | A rate that was live once, then cached or shown past its expiry | No | You, and you may not know it |

A stale quote is the sneaky one. It looks like a live quote on screen. The number just stopped being true a while ago. The most common cause is an application that fetches a rate when a page loads and lets the user sit on it for ten minutes.

For the full quote lifecycle, including what happens when a quote expires and how window length should shape your UX, read [on/off ramp liquidity with live quotes](/resources/more/on-off-ramp-liquidity-live-quotes).

## Why is quote freshness a liquidity signal?

Because a provider can only commit to a rate it can fill. Freshness and bindingness are what real liquidity looks like from the outside.

A provider that holds local-currency inventory, or has direct access to market makers who do, can price a trade and hold that price for a few minutes. It knows it can deliver. A provider that has to go find the reais after you confirm can't make that promise, so it gives you an indicative rate instead and settles at whatever it gets.

Three things to read from a provider's quotes:

- **Does it bind at all?** No quote id, no expiry, no liquidity commitment.
- **How long is the window?** Very short windows, under 10 seconds on a consumer flow, usually mean thin liquidity or a provider pushing its risk onto you.
- **Does the rate hold across sizes?** A spread that stays flat from 500 to 50,000 dollars means the depth is real. A spread that widens fast means the good inventory runs out early.

This is the same test as in [what a liquidity market is](/resources/more/what-is-a-liquidity-market-cross-border-payments): the quote is the visible edge of the liquidity behind it.

## How does a provider build a live quote?

A live quote has four ingredients, calculated in one synchronous request:

1. **A reference rate.** The current market rate for the pair, from interbank FX feeds and trading venues.
2. **The provider's source of liquidity.** Its own inventory, market makers, or local exchange partners, at the size requested.
3. **Spread and fees.** The provider's margin on the rate, plus any flat or percentage fees and network costs.
4. **A lock window.** How long the provider will honor the result. The provider carries the market risk inside that window, which is why windows are minutes, not hours.

A well-built quote response shows the first and third ingredients side by side, so you can see the spread. At BlindPay, every payout quote returns `commercial_quotation` (the market rate) next to `blindpay_quotation` (the rate after BlindPay's margin), plus `sender_amount`, `receiver_amount`, and each fee. The gap between the two rates is the spread, on every quote. [Stablecoin API quotes explained](/resources/more/stablecoin-api-quotes-explained) walks through every field.

## Spread vs slippage: which one are you paying?

Both, possibly. They are different kinds of cost.

- **Spread** is the provider's margin, visible in the quote, agreed before you send.
- **Slippage** is an unagreed difference that shows up after the payment settles.

A binding live quote converts potential slippage into visible spread. The provider prices its risk for the window into the rate, and you see that price before you say yes. So a live quote with a slightly wider spread can cost less than a tight indicative rate plus slippage. The only way to know is to compare settled amounts, not screen rates. [Stablecoin liquidity providers vs bank FX desks](/resources/more/stablecoin-liquidity-provider-vs-fx-desk) covers the rest of the hidden-cost list.

## What should you check before trusting a quote-then-execute flow?

Run through this list against any provider's docs and sandbox:

1. **Rate lock duration.** The quote response states an expiry, and you read it from the response instead of hardcoding it.
2. **Slippage tolerance.** The payment executes at the quoted rate or is rejected. Any tolerance band, even 0.5 percent, means the quote is not binding.
3. **Settlement guarantee.** The recipient gets the quoted `receiver_amount`, not an amount recalculated at execution.
4. **Expiry behavior.** Submitting against an expired quote fails with a distinct error code, so your client knows to re-quote instead of retrying blindly.
5. **Mid-transaction expiry.** You know what happens when a slow step, like an on-chain approval, outlasts the window. The safe answer is to re-quote before executing.
6. **One quote per payment.** A quote id backs a single payment, which adds a second layer against double-sends on top of your idempotency keys.
7. **Itemized fees.** Rate, spread, flat fee, and network fee are separate fields, so the amount on screen matches the amount that settles.
8. **Sandbox parity.** Expiry and rejection behave the same in sandbox as in production, or your failure paths ship untested.

BlindPay's answers, for reference: payout quotes expire five minutes after creation by default (SEPA quotes can be shorter), with `expires_at` in epoch milliseconds. A quote backs one payout, and an expired quote is rejected rather than executed at a new rate. The payout runs on the quote's numbers when you create it inside the window.

## What does a quote-then-execute flow look like in an API?

A typical REST flow for an off-ramp payout has five steps. This is BlindPay's shape, but most stablecoin APIs follow the same pattern.

**Step 1. Request a quote.**
`POST /v1/instances/{instance_id}/quotes` with the destination `bank_account_id`, `request_amount` in minor units (10000 means 100.00), `currency_type` (which side the amount is on), `cover_fees` (who pays), and the funding `network` and `token`.

**Step 2. Read the response and show it.**
The response returns the quote `id`, `expires_at`, `commercial_quotation`, `blindpay_quotation`, `sender_amount`, `receiver_amount`, and fees. Display `receiver_amount` with a countdown driven by `expires_at`.

**Step 3. Authorize the funding, if needed.**
For a self-custodied EVM wallet, sign the ERC-20 `approve` for the exact amount in the quote's `contract` payload. A BlindPay-managed wallet skips this step.

**Step 4. Execute against the quote.**
`POST /v1/instances/{instance_id}/payouts/evm` with the `quote_id` and the sender wallet address, before `expires_at`. If the quote expired, request a new one, show the new numbers, and execute against the new id.

**Step 5. Confirm settlement.**
Listen for the `payout.complete` webhook, which fires when the payout reaches `completed`, `failed`, or `refunded`. Store the quoted and delivered amounts together for reconciliation.

The same flow runs from the terminal with the BlindPay CLI (`blindpay quotes create`, then `blindpay payouts create --quote-id qu_...`) and from the official SDKs for Node.js, Python, and Go, as well as PHP and Swift.

## How do you measure slippage in production?

Log three numbers on every payout: the quoted rate at confirmation, the quoted `receiver_amount`, and the amount that actually landed. Then track, per corridor:

- **Realized slippage.** Delivered amount against quoted amount. On a binding quote, this should be zero, every time.
- **Expiry rate.** The share of quotes that expire before the user confirms. A high rate means your UX fetches quotes too early or the window is too short.
- **Re-quote delta.** How much the amount moves between an expired quote and its replacement. Large deltas on a corridor are a volatility warning.

If realized slippage is ever non-zero on a "live" quote, you have learned something important about your provider.

## What to do next

Pick one corridor and run the eight-point checklist in a sandbox: request a quote, let it expire, submit it anyway, and confirm you get a clean expiry error. Then read the [payout quotes documentation](/docs/payout-quotes) for the full request and response, or follow the [payout quickstart](/docs/quickstart-payout) to run the whole flow on a development instance.

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