> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cbpayapp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payout rate sources and indicative FIFO quotes

> Understand lot, blend and spot pricing and preview an indicative FIFO quote

export const EnvUrls = ({lang = "en"}) => {
  const T = {
    en: {
      test: "Test",
      live: "Live",
      hint: "Same API on both environments — build against test first, then go live by swapping the base URL and the key.",
      guide: "Environments and testing",
      href: "/en/environment-testing"
    },
    es: {
      test: "Test",
      live: "Live",
      hint: "La misma API en ambos ambientes — construye primero contra test y pasa a live cambiando la URL base y la key.",
      guide: "Entorno y pruebas",
      href: "/es/environment-testing"
    },
    zh: {
      test: "Test",
      live: "Live",
      hint: "两个环境的 API 完全一致——先在 test 环境构建，再通过切换基础 URL 和密钥上线。",
      guide: "环境与测试",
      href: "/zh/environment-testing"
    }
  };
  const t = T[lang] || T.en;
  const row = (label, url, keyPattern, badgeCls) => <div className="flex flex-wrap items-center gap-2 px-3 py-2">
      <span className={"rounded px-1.5 py-0.5 text-xs font-semibold uppercase tracking-wide " + badgeCls}>
        {label}
      </span>
      <code className="text-xs">{url}</code>
      <span className="text-xs text-gray-400 dark:text-zinc-500">·</span>
      <code className="text-xs">{keyPattern}</code>
    </div>;
  return <div className="my-4 rounded-xl border border-gray-200 dark:border-zinc-700 divide-y divide-gray-200 dark:divide-zinc-700 text-sm not-prose">
      {row(t.test, "https://cryptobank.qbank.cl/platform", "pk_test_...", "bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-300")}
      {row(t.live, "https://api.qbank.cl/platform", "pk_...", "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-300")}
      <p className="px-3 py-2 text-xs text-gray-500 dark:text-zinc-400 m-0">
        {t.hint} <a href={t.href}>{t.guide} →</a>
      </p>
    </div>;
};

<EnvUrls lang="en" />

## Rate source and indicative FIFO quote

Payout responses may include `rate_source` so you can understand where the
execution market rate came from:

| Value | Meaning |
| - | - |
| `lot` | The local amount was fully covered by the organization's FIFO fiat inventory. |
| `blend` | FIFO inventory covered part of the amount and the remainder used spot. |
| `spot` | No eligible FIFO inventory was used. |

The field is available on payout creation and payout detail when attribution is
loaded. It may be absent on historical or list rows. It does not change the
debit, fee or webhook contract.

### Current payout quote in `GET /v1/rates`

The account-facing rates response keeps the payout field name `rate`. This is
the executable-market quote for the next payout: the platform checks the
oldest open FIFO lot for the country's currency. When eligible inventory is
available, `rate_source` is `lot`; otherwise the quote uses spot and
`rate_source` is `spot`. A failed inventory read also falls back to `spot`;
the payout debit itself remains fail-closed.

`payin_rate` is the deposit-side quote. In USDT v1 it can be backed by enabled
payin lots funded by settled `buy_crypto` trades; `payin_rate_source` reports
`lot` or `spot`. Payin create/detail responses can include `rate_source` when a
quote was loaded. Card payins remain spot-priced. The organization-admin
endpoint exposes the same distinction with `payout_rate`, `payin_rate`,
`rate_source` and `payin_rate_source`.

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "rates": {
    "chile": {
      "currency": "CLP",
      "rate": "910.896551",
      "rate_source": "lot",
      "payin_rate": "955.10",
      "payin_rate_source": "spot"
    }
  }
}
```

This per-country value is an indicative next-payout view. A larger payout can
consume multiple lots; use the opt-in `lot_quote` below for an amount-specific
indicative quote, and use the payout response plus final webhook as the
authoritative execution record.

To preview an indicative inventory-aware quote, add `currency` and `amount` to
`GET /v1/rates`:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl "https://api.qbank.cl/platform/v1/rates?currency=CLP&amount=100000.00"   -H "Authorization: Bearer <token>"
```

The normal rates response can then contain:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "lot_quote": {
    "currency": "CLP",
    "amount": "100000.00000000",
    "market_rate": "13.42150000",
    "rate_source": "blend",
    "marked_rate": "13.28728500",
    "indicative": true
  }
}
```

`lot_quote` is read-only and indicative. Execution locks inventory inside the
debit transaction, so a concurrent payout can change the result. `marked_rate`
is optional. Quote validation errors are values inside the normal `200` rates
response: `invalid_amount`, `currency_not_supported` or `quote_unavailable`.

The quote does not guarantee a future payout price. The payout response and
the final `payout_status_changed` event remain the authoritative records.
For payins, the quote is fixed before the asynchronous credit boundary; FIFO
consumption records inventory attribution at credit time. A shortfall falls
back to spot and raises an operator alert without changing the quoted credit.

### Quote statuses

| Status | Meaning | Next action |
| - | - | - |
| `indicative` | The quote was calculated without execution locks. | Create the payout with the same idempotency key and read its executed `rate_source`. |
| `executed` | The payout response contains the authoritative attribution. | Persist the response and final webhook for reconciliation. |
| `error` | The response contains `invalid_amount`, `currency_not_supported` or `quote_unavailable`. | Correct the inputs or retry the read-only quote; do not create a payout from the error. |

### SEPA EUR rate key

The single Europe (`EU`)/EUR/`sepa` routing corridor shares one rate
key: `sepa`, with `currency: "EUR"`. The payout catalog returns `country:
"EU"` for this row, while the beneficiary's actual country comes from the
IBAN. The payout fee and FX spread resolve on the `EU` pricing row.
`rate_source` still describes the executable payout quote (`lot` or `spot`);
`payin_rate` remains the deposit-side spot quote.

<AccordionGroup>
  <Accordion title="Does this quote reserve inventory?">
    No. It is read-only and indicative. The payout debit transaction locks and
    consumes inventory atomically.
  </Accordion>

  <Accordion title="What should I store for reconciliation?">
    Store the payout response and its final `payout_status_changed` event. Use
    `rate_source` as the execution provenance; do not treat `lot_quote` as a
    guarantee.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.