---
title: "How to calculate FX spread on an international payment (with worked examples)"
seoTitle: "How to calculate FX spread: formula and worked examples"
description: "FX spread % = (mid rate - offered rate) / mid rate x 100. Here is how to get the mid rate, fix the quote direction, and price the spread in dollars."
date: "2026-10-03"
updated: "2026-10-03"
category: "payments"
author: "BlindPay Team"
howto:
  name: "How to calculate the FX spread on an international payment"
  steps:
    - name: "Capture the mid-market rate at the moment of the quote"
      text: "Take the mid-market rate from a live source at the same time the provider quotes you. A rate from yesterday's fixing or a weekend screen will make the spread look bigger or smaller than it is."
    - name: "Put both rates in the same direction"
      text: "Express the mid rate and the offered rate as units you receive per unit you send, for example BRL per USD. If one is quoted the other way round, invert it before comparing."
    - name: "Compute the spread and convert it to money"
      text: "Spread % = (mid rate - offered rate) / mid rate x 100. Multiply the spread % by the amount you send to get the cost in your own currency, then add any separate fees for the all-in cost."
faq:
  - q: "What is the formula for FX spread?"
    a: "When you sell one currency to receive another, spread % = (mid-market rate - offered rate) / mid-market rate x 100, with both rates written as units received per unit sent. A mid rate of 5.40 BRL per USD and an offered rate of 5.346 gives a 1.0% spread. On $5,000, that is $50 before any separate fee."
  - q: "Where can I find the mid-market exchange rate?"
    a: "Live data feeds and market screens show a real-time mid rate. Official reference rates are slower but public: the ECB publishes euro reference rates around 16:00 CET on working days, Banxico releases the FIX from 12:00 on banking days, and Brazil's central bank sets PTAX from four dealer surveys between 10:00 and 13:10 Brasília time."
  - q: "Is a zero-fee transfer free?"
    a: "Rarely. A provider that charges no fee usually earns its margin in the exchange rate instead. Compare the amount the recipient gets with the amount sent multiplied by the mid rate. A zero-fee quote with a 2% spread costs more than a quote with a $30 fee and a 0.5% spread on a $10,000 payment."
  - q: "Why does the spread change when I invert the quote?"
    a: "Because a percentage measured against a different base gives a slightly different number. A 1.00% spread on BRL per USD becomes about 1.01% when you express both rates as USD per BRL. The money lost is the same. Pick one direction, units received per unit sent, and use it for every provider you compare."
  - q: "How do I see the spread in a BlindPay quote?"
    a: "Every BlindPay quote returns commercial_quotation, the raw market rate, next to blindpay_quotation, the rate net of BlindPay's fee. The gap between them is BlindPay's FX margin. The flat_fee and partner_fee_amount fields list the separate fees, and receiver_amount shows what lands in the bank account."
  - q: "Should I use the central bank reference rate as the mid-market rate?"
    a: "Use it as a sanity check, not as the exact benchmark. Reference rates such as PTAX and the Banxico FIX are calculated once a day from earlier market data, so the live market can move away from them within hours. For a quote you are about to accept, compare against a live mid rate taken at the same minute."
---

The FX spread is the gap between the mid-market exchange rate and the rate a provider gives you. Spread % = (mid rate - offered rate) / mid rate x 100. On a $5,000 payment, a 1.0% spread costs $50 before any listed fee. BlindPay quotes show the market rate and the rate after fees side by side, so the spread is visible before you confirm.

The math is easy. Getting it right is not, because most mistakes happen before the formula: a stale mid rate, a quote written upside down, or a fee taken out before conversion.

**Key takeaways**

- Spread % = (mid - offered) / mid x 100, with both rates written as units received per unit sent.
- Money cost = spread % x amount sent. A 1.0% spread on $5,000 is $50.
- The cleanest all-in check: 1 - (amount received / (amount sent x mid rate)). It catches spread and fees in one number.
- Central bank reference rates (PTAX, Banxico FIX, ECB) are useful sanity checks but are not live mid rates.
- A "no fee" quote usually prices its margin into the rate. Compare amounts received, not fee lines.

## What is an FX spread?

An FX spread is the difference between the mid-market rate and the rate you actually get, usually expressed as a percentage of the mid rate. It is how most providers earn money on a currency conversion.

The **mid-market rate** is the midpoint between the price at which banks are buying a currency and the price at which they are selling it in the wholesale market. Nobody trades at exactly that rate, which is why it works as a neutral yardstick.

The **offered rate** (also called the final rate or customer rate) is what the provider applies to your payment. The gap between the two is the **spread**, sometimes called the markup or margin. A separate **fee** is anything charged on top, such as a flat $25 or a percentage of the amount.

For the wider cost picture, including correspondent fees and receiving bank charges, see [hidden fees in international wires](/resources/more/hidden-fees-international-wires-our-sha-ben) and [how much cross-border payments cost in 2026](/resources/more/cross-border-payment-costs-2026).

## What is the formula for FX spread?

When you sell one currency to receive another, spread % = (mid rate - offered rate) / mid rate x 100. Both rates must be in the same direction: units of the currency you receive per one unit of the currency you send.

Direction is where most calculations go wrong. Three cases:

- **Selling USD to pay in BRL.** Rates are quoted as BRL per USD. You get fewer reais than mid, so the offered rate is lower: spread = (mid - offered) / mid.
- **Buying USD with BRL.** Rates are still quoted as BRL per USD, but now you pay more reais than mid for each dollar: spread = (offered - mid) / mid.
- **Inverted quotes.** Some providers quote USD per BRL (0.1852) instead of BRL per USD (5.40). Invert one of them before comparing, or you will subtract numbers that mean different things.

One rule handles all three: convert everything to "how much do I receive for one unit I send", then cost % = 1 - (offered / mid). Inverting changes the percentage a little because the base changes. A 1.00% spread measured in BRL per USD shows up as about 1.01% in USD per BRL. The money lost is identical, so pick one convention and stick to it.

## How do you calculate FX spread in 3 steps?

Take a live mid rate, align the direction, then compute the percentage and convert it to money. Here it is on a $5,000 payment from USD to BRL.

Assumptions (illustrative, not a live quote or a BlindPay price): mid-market rate 5.4000 BRL per USD, offered rate 5.3460 BRL per USD, no separate fee.

1. **Capture the mid rate at the same moment.** Take the mid from a live source at the minute you request the quote: 5.4000. A rate from yesterday's fixing would distort everything that follows.
2. **Align the direction.** Both rates are already BRL per USD, the currency you receive per unit you send. Nothing to invert.
3. **Compute the spread and the money.** (5.4000 - 5.3460) / 5.4000 = 0.0100, so 1.00%. Multiply by the amount sent: 1.00% x $5,000 = $50.

Check it from the recipient's side. At mid, $5,000 buys R$27,000. At 5.3460, it buys R$26,730. The R$270 gap, divided by the 5.40 mid rate, is $50. Same answer, which is the point: if the two methods disagree, one of your inputs is wrong.

## Where do you get the mid-market rate?

A live market data feed gives you a real-time mid rate. Official reference rates are free and public but are set once a day, so treat them as a check on the live number rather than a replacement for it.

| Source | Who publishes it | When it is set | Best use |
| --- | --- | --- | --- |
| Live mid from a market data feed or trading screen | Data vendors, banks, FX platforms | Continuously during market hours | Benchmarking a quote you are about to accept |
| WM/Reuters benchmark rates | LSEG | Daily fixings, the best known around 4pm London | Month-end valuation, accounting, contracts that reference it |
| [ECB euro reference rates](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html) | European Central Bank | Around 16:00 CET on working days, except TARGET closing days | EUR sanity checks; the ECB says the rates are for information only and discourages using them for transactions |
| [Banxico FIX](https://www.banxico.org.mx/tipcamb/tipCamMIAction.do?idioma=sp) | Banco de México | Released from 12:00 on banking days, from an average of wholesale market quotes for settlement two banking days later; published in the Diario Oficial the next banking day | USD/MXN reference for contracts and peso-denominated obligations |
| [PTAX](https://www.bcb.gov.br/conteudo/relatorioinflacao/EstudosEspeciais/EE042_A_taxa_de_cambio_de_referencia_Ptax.pdf) | Banco Central do Brasil | Four dealer surveys at random times inside 10:00-10:10, 11:00-11:10, 12:00-12:10 and 13:00-13:10 Brasília time | USD/BRL reference for contracts, tax, and accounting |

Two things to know about reference rates. First, they lag. PTAX is built from surveys that end around 13:10 in Brasília, so by late afternoon the live market can sit well away from it. Second, they are not quotes. Nobody will deal with you at PTAX or the FIX, so a provider quoting a little away from them is not necessarily overcharging.

For stablecoin routes there is one more wrinkle. USDC and USDT trade close to one dollar, but not at exactly one dollar every second. When the quote is in USDC per BRL, compare against the USD mid and accept that a few hundredths of a percent may come from the token, not the provider.

## How do you compare a "no fee" quote with a quote that charges a fee?

Use the all-in formula: cost % = 1 - (amount received / (amount sent x mid rate)). It folds spread and fees into one number, whatever the provider calls them.

Assumptions (illustrative): $10,000 USD to MXN, mid-market rate 18.50 MXN per USD, so $10,000 is worth MXN 185,000 at mid.

| | Quote A: "no fee" | Quote B: fee plus tighter rate |
| --- | --- | --- |
| Fee | $0 | $30, deducted before conversion |
| Offered rate | 18.13 MXN per USD | 18.40 MXN per USD |
| Spread on the rate | 2.00% | 0.54% |
| Amount converted | $10,000 | $9,970 |
| Recipient gets | MXN 181,300 | MXN 183,448 |
| Shortfall vs mid (MXN 185,000) | MXN 3,700 | MXN 1,552 |
| All-in cost | 2.00%, about $200 | 0.84%, about $84 |

Quote A looks free and costs more than twice as much. That is why fee lines alone tell you very little.

Note the order of operations in Quote B. The $30 is taken before conversion, so the recipient loses the fee at the offered rate, not at mid. Some providers deduct fees from the local currency after conversion instead. The all-in formula doesn't care which. It only looks at what arrives.

The [crypto on-ramp fees guide](/resources/more/crypto-on-ramp-fees-explained) runs the same kind of comparison for the payin side, and [stablecoin FX slippage](/resources/more/stablecoin-fx-slippage-live-quotes) covers the cost that appears after you accept, when the rate you get drifts from the rate you were shown.

## What mistakes make a spread calculation wrong?

Most wrong answers come from bad inputs, not bad arithmetic. Five to check before you trust the number:

1. **Stale mid rate.** Comparing a 3pm quote with the morning's PTAX or a Friday close makes any provider look good or bad depending on how the market moved.
2. **Weekend rates.** FX markets largely pause from Friday evening to Sunday evening. Quotes given over the weekend can carry a wider spread to cover the risk of Monday's open, and a Friday mid is a weak benchmark for them.
3. **Mixed directions.** Subtracting a USD per BRL rate from a BRL per USD rate produces nonsense. Align first.
4. **Ignoring fees taken from the principal.** Intermediary banks on a SWIFT payment can deduct charges in transit, so the recipient gets less than the quote suggested. That is a cost even though it never appears as a rate.
5. **Comparing indicative rates.** A rate on a website is not a quote. Only a firm quote with an expiry time tells you what you will pay. [Stablecoin API quotes explained](/resources/more/stablecoin-api-quotes-explained) covers what a firm quote locks.

## How do you read the spread in a BlindPay quote?

Every BlindPay quote shows both rates and every fee line, so you can compute the spread without a separate data feed. The fields come straight from the [payout quote response](/docs/payout-quotes).

| Field | What it is | How to use it |
| --- | --- | --- |
| `commercial_quotation` | The raw market exchange rate | Your market benchmark for this quote |
| `blindpay_quotation` | The rate net of BlindPay's fee | The offered rate in the spread formula |
| `flat_fee` | The flat-fee component | Add it to the all-in cost |
| `partner_fee_amount` | Your own markup, if you passed a `partner_fee_id` | The margin your platform adds for its users ([partner fees](/docs/learn/partner-fees)) |
| `sender_amount` / `receiver_amount` | Amount sent and amount received, in minor units | The inputs to the all-in formula |
| `expires_at` | Quote expiry in epoch milliseconds, 5 minutes by default | The window in which the numbers hold |

So BlindPay's FX margin on a quote = (`commercial_quotation` - `blindpay_quotation`) / `commercial_quotation`. To check the market rate itself, compare `commercial_quotation` with a live mid rate from your own source at the same minute.

For example, a quote with `commercial_quotation` 5.40 and `blindpay_quotation` 5.373 carries a 0.5% FX margin (illustrative numbers). Add `flat_fee` and any `partner_fee_amount`, and the all-in cost falls out of `receiver_amount`.

BlindPay quotes use real-time rates and lock rate and fees for the quote's lifetime, so the spread you calculate is the spread you get if you execute before `expires_at`. Payouts settle over Pix and SPEI in minutes, and over ACH, SEPA, and SWIFT (POBO/COBO) on the rail's schedule ([cut-off times](/docs/kb/cut-off-times)). There is no pre-funding: the quote is funded when you execute it.

Plans are published on the [pricing page](/pricing). Per-transaction costs show up in each quote rather than in a rate card, which is why the fields above matter.

## What to do next

Pull one real quote for your main corridor, take a live mid rate at the same minute, and run both formulas: spread % on the rate, then the all-in cost % on the amount received. If you are building on BlindPay, create a test quote from the [payout quickstart](/docs/quickstart-payout) and compute the margin from `commercial_quotation` and `blindpay_quotation`. Then read [what real-time cross-border settlement is](/resources/more/what-is-real-time-cross-border-settlement) to see where the rate fits in the rest of the payment.
