---
url: /docs/payable-quotes.md
description: >-
  Resolve a boleto or PIX code, see the real amount and beneficiary before
  committing, and lock the exchange rate for 5 minutes.
---

A payable quote does two jobs at once: it **reads the bill** and it **prices it**. You send the code, and the response tells you who gets paid, how much they are owed today, and how much stablecoin that costs. A payable can only be created against a valid, unexpired quote.

This is the step where a bad code fails. Nothing is charged and no payable exists until you commit the quote.

The quote is also where the surprises surface: a boleto that has accrued a fine, a bill that cannot be paid today because it is not a banking day, or a code you have already paid.

For an external wallet, the quote also returns the on-chain payload you need to authorize the pull: the ERC-20 contract address, ABI, and the exact decimal-adjusted amount to approve.

## How it works

You pass the instrument (`type` plus the raw `payload`) and the customer paying it. BlindPay resolves the code with the Brazilian rail, then prices the conversion. The quote expires **5 minutes** after creation.

Quotes are ephemeral: nothing appears in your payables list until you commit one. An abandoned quote simply expires.

### The resolved bill

The response describes the bill as the rail sees it right now:

| Field | What it is |
| --- | --- |
| `amount` | What is owed **today**, in BRL cents. Includes any fine, interest or discount |
| `original_amount` | The face value before those adjustments |
| `beneficiary_name`, `beneficiary_tax_id` | Who is actually being paid |
| `due_date` | The bill's due date (boleto) |
| `scheduled_date` | The day it will really execute, when that is not today |

`amount` and `original_amount` differ on an overdue boleto. Show `amount`, since that is what leaves the account.

Quote an overdue boleto twice on different days and you can get two different amounts, because interest keeps accruing. Always execute against a fresh quote rather than a cached figure.

### scheduled\_date

Boletos only clear on Brazilian banking days. When a boleto cannot go out today, the quote returns a `scheduled_date` and the payable will sit in `processing` until that day. This is on the quote deliberately, so you can show your user the real date **before** they commit rather than after.

A boleto whose `due_date` falls before the day it could execute is refused here with `PAYABLES_BOLETO_WOULD_BE_OVERDUE`, rather than being paid late. See [Payables](/payables) for the full banking-calendar behavior.

### Duplicates

If the same code is already live or paid as another payable, the quote returns `duplicate_of_payable_id`.

| Instrument | Committing a duplicate |
| --- | --- |
| Boleto | Allowed with `force: true`. The clearing network rejects true double payments itself |
| PIX code | Always refused. `force` is not accepted, because the PIX rail has no duplicate detection and would simply pay twice |

### Codes that cannot be quoted

| Situation | Error |
| --- | --- |
| Amount-less static PIX code (payer chooses the value) | `pix_code_amount_required` |
| Utility bill or tax slip (arrecadação, 48 digits starting with 8) | `PAYABLES_INSTRUMENT_NOT_SUPPORTED` |
| Already paid, expired or otherwise unpayable | `PAYABLES_ALREADY_PAID_OR_EXPIRED` |
| Not a code we can read | `unresolvable_boleto_code` / `unresolvable_pix_code` |

### network and token

`network` and `token` select the chain and stablecoin the funding wallet sends from. Payables are **EVM only** today: a non-EVM network is refused with `payable_network_not_supported`.

| Instance | Networks | Tokens |
| --- | --- | --- |
| Development | `sepolia`, `base_sepolia`, `arbitrum_sepolia`, `polygon_amoy` | `USDB` only |
| Production | `ethereum`, `base`, `polygon`, `arbitrum` | `USDC` or `USDT` |

You can pass `network` on its own, exactly like a payout, and supply the funding address at commit time. Passing a `wallet_id` or `blockchain_wallet_id` instead pins the quote to that registered wallet, and the address you commit with must match it.

## Prerequisites

You also need a [customer](/overview) whose KYC is approved. Unlike a payout, there is no bank account to register: the bill already names its beneficiary.

## Create a payable quote

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/payable-quotes \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "receiver_id": "re_000000000000",
  "type": "boleto",
  "payload": "34191790010104351004791020150008191070026000",
  "network": "sepolia",
  "token": "USDB"
}'
```

```js [index.js]
const response = await fetch(
  'https://api.blindpay.com/v1/instances/in_000000000000/payable-quotes',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      receiver_id: 're_000000000000',
      type: 'boleto',
      payload: '34191790010104351004791020150008191070026000',
      network: 'sepolia',
      token: 'USDB',
    }),
  }
)

const quote = await response.json()
```

```bash [cURL]
curl --request POST \
  --url https://api.blindpay.com/v1/instances/in_000000000000/payable-quotes \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "receiver_id": "re_000000000000",
  "type": "pix_code",
  "payload": "00020126580014br.gov.bcb.pix0136...",
  "network": "base_sepolia",
  "token": "USDB"
}'
```

```js [index.js]
const response = await fetch(
  'https://api.blindpay.com/v1/instances/in_000000000000/payable-quotes',
  {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      receiver_id: 're_000000000000',
      type: 'pix_code',
      payload: '00020126580014br.gov.bcb.pix0136...',
      network: 'base_sepolia',
      token: 'USDB',
    }),
  }
)

const quote = await response.json()
```

The response carries a `contract` object when the funding wallet is external. Use it to build the `approve` call before committing: see [Payable with EVM](/payable-evm).

## Related

* [Payables](/payables): lifecycle, webhooks and the banking calendar
* [Payable with EVM](/payable-evm): fund from an external wallet
* [Payable with managed wallet](/payable-managed-wallet): fund from a BlindPay-custodied wallet
