Fix what the recipient gets, not what you send. How receiver-side quotes and cover_fees land exact amounts over Pix, SPEI, and SEPA, with worked examples.
To pay an exact BRL, MXN, or EUR amount from USDC, request a receiver-side quote: set currency_type to receiver, put the local amount in request_amount, and set cover_fees to true. The quote returns the USDC sender_amount that delivers that exact amount, locked until expires_at. Execute before then and the number lands.
That is the whole trick. The rest of this guide is the detail that makes it work on Pix, SPEI, and SEPA without surprises.
Key takeaways
currency_type: "receiver" plus cover_fees: true is the pairing for "recipient gets exactly X." With cover_fees: false, the fee comes out of the recipient's amount.2700000. No floats.expires_at.Fix the receiver amount when the obligation is written in local currency. Fix the send amount when the budget is written in dollars. The quote can do either; your job is to pick the side that matches the contract.
The quotes explainer covers what currency_type and cover_fees mean. This is about which combination fits which job.
| Use case | Obligation is in | Quote side | cover_fees | Why |
|---|---|---|---|---|
| Supplier invoice in Brazil | BRL | receiver | true | The invoice says R$27,000.00. Anything less is a short payment. |
| Contractor salary in Mexico | MXN | receiver | true | The contract fixes pesos. The company absorbs the fee. |
| Rent or tuition in the euro area | EUR | receiver | true | The bill is in euros and must clear in full. |
| Marketplace seller payout | USD balance | sender | false | The seller earned a USD balance and gets the net in local currency. |
| Treasury sweep to a local account | USDC on hand | sender | false | You move a USDC amount and accept the local result. |
A rule of thumb: if someone will check the local number against a document, quote the local number.
You tell BlindPay the fiat amount the bank account must receive. BlindPay prices the conversion at request time and returns how much stablecoin the funding wallet must send, plus every fee line, locked for the quote's window.
The request goes to POST /v1/instances/{instance_id}/quotes:
The response carries id, expires_at (epoch milliseconds), commercial_quotation (the market rate), blindpay_quotation (the rate net of BlindPay's fee), sender_amount, receiver_amount, and the fee fields. The payout quotes reference lists every field.
Two details catch teams the first time.
request_amount is an integer. R$27,000.00 is 2700000, and $35,000.00 MXN is 3500000. Convert once, at the edge of your system.receiver means the fiat side. On a payin quote, receiver means the stablecoin side. A shared helper that ignores this quotes the wrong side.The same request shape works across rails. What changes is the bank account behind bank_account_id and a couple of rail rules.
| Brazil | Mexico | SEPA zone | |
|---|---|---|---|
| Rail | Pix | SPEI | SEPA |
| Recipient detail | Pix key (CPF, CNPJ, phone, email, or random key) | 18-digit CLABE | IBAN and BIC, plus beneficiary name and address |
| Receiver-side minimum | Fee only | Fee only | 10 EUR (11 USDC on the sender side) |
| Quote window | 5 minutes by default | 5 minutes by default | Can be shorter than 5 minutes |
| Estimated arrival in BlindPay's docs | Instant | Instant | About 1 business day |
Pix and SPEI both run around the clock. The Central Bank of Brazil operates Pix as an instant payment system, and Banco de México operates SPEI around the clock. SEPA is the euro area's common framework for euro transfers, described by the European Central Bank.
For which details each rail needs, see Pix keys, CPF, and CLABE explained and the SEPA off-ramp guide.
The quote tells you. You never compute sender_amount yourself. But you should know how to read it, so you can check the cost against the market.
Illustrative example. These rates are made up for the arithmetic. They are not BlindPay pricing.
| Brazil invoice | Mexico salary | Euro rent | |
|---|---|---|---|
| Receiver amount (fixed) | R$27,000.00 | $35,000.00 MXN | €2,500.00 |
Market rate (commercial_quotation) | 5.40 BRL per USDC | 18.50 MXN per USDC | 0.8600 EUR per USDC |
sender_amount returned | 5,025.13 USDC | 1,901.40 USDC | 2,921.58 USDC |
| Effective rate (receiver ÷ sender) | 5.3730 | 18.4075 | 0.8557 |
| USDC needed at the market rate | 5,000.00 | 1,891.89 | 2,906.98 |
| All-in cost vs market | 25.13 USDC (50 bps) | 9.51 USDC (50 bps) | 14.61 USDC (50 bps) |
The math for Brazil: 27,000 ÷ 5,025.13 = 5.3730 BRL per USDC delivered. At the market rate, 27,000 ÷ 5.40 = 5,000.00 USDC. The difference, 25.13 USDC, is everything you paid: spread plus fees. As a share: (5.40 - 5.373) ÷ 5.40 = 0.50%, or 50 basis points.
That one number is the honest comparison between providers. Ask each for a receiver-side quote of the same amount at the same moment, then compare sender_amount. For the spread side of that math, see how to calculate FX spread.
Only the USDC side. The local amount is what you asked for, so a new quote keeps it and reprices the stablecoin.
Payout quotes expire 5 minutes after creation by default, and SEPA quotes can be shorter because the rail's own deadline can be tighter. An expired quote is rejected. Nothing executes at a new rate behind your back.
So the re-quote loop for an exact amount is simple:
request_amount.sender_amount with the old one.The local number never changes in that loop, which is why finance teams like receiver-side quotes for payables. The risk that moves is yours to see before you send. Who carries FX risk at each step walks through who holds the rate between quote, execution, and settlement.
Most failures are setup mistakes, not rate problems.
sender with a BRL number in request_amount sends 27,000 USDC. Test both sides in development before you ship.cover_fees: false on a fixed obligation. The fee comes out of the recipient's amount, and the invoice is short. Use true when the number must land in full.27000.00 is rejected. Send 2700000.expires_at and divide by 1,000 if your library wants seconds.quote_id backs one payout. The second payout against it fails.sepa_minimum_is_10_eur.The stablecoin payout mistakes guide covers the rest, from wrong networks to bad bank details.
Store the quote with the payout. The quote's receiver_amount is the number your obligation should match, and the payout id is what your webhooks report on.
A minimal record per payment:
| Field | Source | Use |
|---|---|---|
| Invoice or payroll line id | Your system | What the payment settles |
quote.id | Quote response | Proof of the locked rate and fees |
receiver_amount | Quote response | Must equal the obligation, in minor units |
sender_amount | Quote response | USDC cost for your ledger |
payout.id | Payout response | Joins webhook events to the obligation |
| Final status | Webhooks | Close the item on completion |
If receiver_amount doesn't equal the invoice amount, stop before executing. That check catches the wrong side, the wrong cover_fees, and a typo in minor units, all at once.
For contractor runs, the stablecoin payroll guide for Latin America shows where this fits in a monthly cycle, and the on/off-ramp liquidity glossary defines every term used here.
Open a free development instance, add a test bank account, and request two quotes for the same local amount: one with cover_fees: true, one with false. Compare receiver_amount on both. Then follow the payout quotes guide to execute against the one that lands the exact number.
Seven places blockchain payments beat bank rails: contractor payroll, remittances, B2B suppliers, marketplaces, 24/7 treasury, bill pay, and PSP payouts.
AP2, ACP, and x402 each verify that an AI agent had permission to spend. Here is what every protocol covers, who backs it, and the reconciliation gap none of them close.
The three roles behind every card program, stablecoin cards included: what each one does, who carries liability, and what to ask a provider.