Quotes
A quote is a priced, time-bound snapshot. It binds the offers, quantities, currency, discount, FX snapshot and total for 15 minutes. It is not a payment and it does not reserve stock.
Code
Required scope: catalog:read in the current handler. The target contract uses
quotes:write; include both on a key that creates quotes during the rollout.
Request
Code
| Field | Rule |
|---|---|
currency | USD, EUR or GBP. Defaults to USD when omitted. |
items | At least one line. Maximum 200 lines. |
offerId | Opaque id from GET /v1/catalog. |
quantity | Integer, at least 1. Total across lines must be 1 to 5,000. |
Agent defaults are 50 lines and 500 units per order unless the principal raises them. Those caps are part of the target agent contract and are not enforced by the current quote handler.
Idempotency-Key is not required on quote creation. If you send one, it is included in the
signature but does not deduplicate quotes. A retry creates another quote with a new id.
Response
Code
| Field | Meaning |
|---|---|
quoteId | Use this in POST /v1/orders or GET /v1/quotes?id=. |
status | open until accepted or expired. |
totalMinor | Sum of finalUnitMinor * quantity. |
expiresAt | Absolute expiry, 15 minutes after creation. |
fxAsOf | FX snapshot used for EUR or GBP conversion. |
capped | True when any line was raised to the margin floor. |
lines | Public line items. Upstream identifiers are omitted. |
Read a quote
GET /v1/quotes?id={quoteId} returns the same public shape. This helper is Preview: it is
implemented but not yet in the published OpenAPI document. It requires catalog:read and
only returns quotes owned by the calling partner.
The target contract also describes GET /v1/quotes/{id}. Use the query form until that path is
published.
Expiry and capped prices
- A quote expires 15 minutes after creation. An order with an expired quote returns
409 quote_expired. capped: truemeans the partner's requested discount would breach the contribution-margin floor.finalUnitMinorwas raised to the floor. Do not recompute the total fromrequestedPercent.- A quote can be accepted once. A second order with the same quote returns
404 quote_not_foundbecause the quote is no longeropen.
What the quote does not do
- It does not reserve stock.
- It does not debit the wallet.
- It does not guarantee that the upstream product will still be available at order time.
- It does not lock the FX rate beyond its own expiry.
The order rechecks the current price and availability against the quote snapshot. A mismatch
returns 409 price_changed, and no order is created and no funds are debited.
One-call alternative
POST /v1/orders accepts currency, items and expectedTotalMinor instead of
quoteId. The API creates an internal quote, checks the expected total and proceeds. Use this
shape only when the agent has a clear mandate and a maximum total. See Orders.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | validation_error | Missing items, bad currency, non-integer quantity, more than 200 lines or more than 5,000 units. |
| 409 | out_of_stock | At least one offer is unavailable. |
| 409 | quote_expired | The quote is older than 15 minutes. |
| 503 | fx_unavailable | EUR or GBP rate missing or stale. |
| 429 | rate_limited / quota_exceeded | Quote limit reached. No quote row was created. |
Related
- Orders for the purchase step.
- Wallet for the funds that pay for an order.
- Agent payment for budgets and mandates.