Quotes
The durable quote store. A quote is priced and saved, can be retrieved by any channel allowed to see it, revalidated, and accepted, which freezes its commercial conditions for the order engine.
| Operation | Endpoint |
|---|---|
| Price alternative transport connections for a quote | POST /quote-store/connections/alternatives |
| Price and save a quote | POST /quote-store/quotes |
| Retrieve a quote | GET /quote-store/quotes/{reference} |
| Accept a quote and freeze its conditions | POST /quote-store/quotes/{reference}/accept |
| Read the frozen conditions of an accepted quote | GET /quote-store/quotes/{reference}/frozen-conditions |
| Update a supplier price on a quote line | POST /quote-store/quotes/{reference}/lines/{lineId}/supplier-price |
| Revalidate a quote against current prices | POST /quote-store/quotes/{reference}/revalidate |
Price alternative transport connections for a quote
/quote-store/connections/alternativesHeaders: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
actor | string | min 1 chars | |
agency_ref | string | min 1 chars | |
attributes | map of string | ||
candidates | array of object | yes | at least 1; at most 50 |
candidates[].attributes | map of string | ||
candidates[].available | boolean | default true | |
candidates[].component | map of object | yes | |
candidates[].product_id | string | yes | min 1 chars |
candidates[].product_type | string | min 1 chars | |
channel | string | yes | min 1 chars |
currency | string | yes | pattern ^[A-Z]{3}$ |
customer_ref | string | min 1 chars | |
items | array of object | yes | at least 1; at most 200 |
items[].attributes | map of string | ||
items[].component | map of object | ||
items[].external_price | object | ||
items[].external_price.amount | number | yes | ≥ 0 |
items[].external_price.key | string | yes | min 1 chars |
items[].external_price.supplier_ref | string | yes | min 1 chars |
items[].external_price.valid_until | string (date-time) | yes | |
items[].inventory_ref | string | min 1 chars | |
items[].line_id | string | yes | 1–100 chars |
items[].nights | integer | ≥ 0; default 0 | |
items[].offer | object | ||
items[].offer.id | string | yes | min 1 chars |
items[].offer.version | integer | yes | > 0 |
items[].passengers | integer | > 0; default 1 | |
items[].product_id | string | yes | min 1 chars |
items[].product_type | string | min 1 chars; default "default" | |
items[].quantity | integer | > 0; default 1 | |
market | string | yes | min 1 chars |
replace_line_id | string | yes | min 1 chars |
selling_conditions | array of object | ||
selling_conditions[].code | string | yes | min 1 chars |
selling_conditions[].label | string | ||
selling_conditions[].version | integer | yes | > 0 |
signals | map of object | ||
store_version | integer | > 0 |
Schema: apps/journeys/src/quote-store/contracts.ts (ConnectionAlternativesRequestSchema)
Response 200
{ connections }: the candidates priced; nothing is saved.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 404 | quote_store_not_enabled | The quote store is not enabled for the tenant. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Price and save a quote
/quote-store/quotesPrices the items with the tenant's pricing layers, promotions and selling conditions, and saves the quote with a reference. Field names on the quote store are snake_case.
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
actor | string | yes | min 1 chars |
agency_ref | string | min 1 chars | |
attributes | map of string | ||
channel | string | yes | min 1 chars |
currency | string | yes | pattern ^[A-Z]{3}$ |
customer_ref | string | min 1 chars | |
items | array of object | yes | at least 1; at most 200 |
items[].attributes | map of string | ||
items[].component | map of object | ||
items[].external_price | object | ||
items[].external_price.amount | number | yes | ≥ 0 |
items[].external_price.key | string | yes | min 1 chars |
items[].external_price.supplier_ref | string | yes | min 1 chars |
items[].external_price.valid_until | string (date-time) | yes | |
items[].inventory_ref | string | min 1 chars | |
items[].line_id | string | yes | 1–100 chars |
items[].nights | integer | ≥ 0; default 0 | |
items[].offer | object | ||
items[].offer.id | string | yes | min 1 chars |
items[].offer.version | integer | yes | > 0 |
items[].passengers | integer | > 0; default 1 | |
items[].product_id | string | yes | min 1 chars |
items[].product_type | string | min 1 chars; default "default" | |
items[].quantity | integer | > 0; default 1 | |
market | string | yes | min 1 chars |
selling_conditions | array of object | ||
selling_conditions[].code | string | yes | min 1 chars |
selling_conditions[].label | string | ||
selling_conditions[].version | integer | yes | > 0 |
signals | map of object | ||
store_version | integer | > 0 |
Schema: apps/journeys/src/quote-store/contracts.ts (SaveQuoteRequestSchema)
Response 201
{ quote } with reference, status (open, accepted, expired), lines, totals, versions, sellingConditions, validUntil and retainUntil.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 400 | tenant_required | No tenant could be resolved from the token or the request. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | channel_not_allowed | The channel may not read or write this quote. |
| 404 | quote_store_not_enabled | The quote store is not enabled for the tenant. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Retrieve a quote
/quote-store/quotes/{reference}Returns the stored quote as the given channel may see it. Trade channels also see trade amounts.
Parameters
| Name | In | Required | Notes |
|---|---|---|---|
reference | path | yes | |
channel | query | yes | The channel reading the quote. |
Response 200
{ quote }.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 400 | channel_required | The channel query parameter is required to read a quote. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | channel_not_allowed | The channel may not read or write this quote. |
| 404 | quote_not_found | The quote does not exist. |
| 404 | quote_store_not_enabled | The quote store is not enabled for the tenant. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Accept a quote and freeze its conditions
/quote-store/quotes/{reference}/acceptRevalidates and accepts the quote. If revalidation found differences, pass their hash in acknowledged_differences_hash. The response carries the commercial handover the order engine converts from.
Parameters
| Name | In | Required | Notes |
|---|---|---|---|
reference | path | yes |
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
acknowledged_differences_hash | string | min 1 chars | |
actor | string | yes | min 1 chars |
channel | string | yes | min 1 chars |
Schema: apps/journeys/src/quote-store/contracts.ts (AcceptQuoteRequestSchema)
Response 200
{ quote, handover, revalidation }. The handover has handoverId, the frozen lines, totals, selling conditions, versions and an integrity hash.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 404 | quote_not_found | The quote does not exist. |
| 404 | quote_store_not_enabled | The quote store is not enabled for the tenant. |
| 409 | quote_not_open | The quote is no longer open. |
| 409 | revalidation_blocking | Revalidation found differences that block acceptance. |
| 409 | differences_not_acknowledged | Revalidation found differences that must be acknowledged with their hash. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Read the frozen conditions of an accepted quote
/quote-store/quotes/{reference}/frozen-conditionsThe server's mapping of the accepted handover to the order engine's frozen-conditions document, after its integrity hash is checked. Pass this document to quotation convert or trip handover instead of building it on the client.
Parameters
| Name | In | Required | Notes |
|---|---|---|---|
reference | path | yes |
Response 200
{ frozen }: quoteRef, quoteVersion, frozenAt, currency, market, channel, configVersion, storeVersion, customerRef, lines, promotions and totalMinor.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 404 | quote_not_found | The quote does not exist. |
| 404 | quote_store_not_enabled | The quote store is not enabled for the tenant. |
| 409 | not_accepted | The quote has not been accepted, so it has no frozen conditions. |
| 409 | handover_tampered | The stored handover failed its integrity check. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Update a supplier price on a quote line
/quote-store/quotes/{reference}/lines/{lineId}/supplier-priceParameters
| Name | In | Required | Notes |
|---|---|---|---|
reference | path | yes | |
lineId | path | yes |
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
amount | number | yes | ≥ 0 |
key | string | yes | min 1 chars |
supplier_ref | string | yes | min 1 chars |
valid_until | string (date-time) | yes |
Schema: apps/journeys/src/quote-store/contracts.ts (ExternalPriceInputSchema)
Response 200
{ supplierUpdate: { response, decision, delta, deltaPercent } }; decision is auto_accept or needs_confirmation.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 404 | quote_not_found | The quote does not exist. |
| 404 | quote_store_not_enabled | The quote store is not enabled for the tenant. |
| 409 | quote_not_open | The quote is no longer open. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Revalidate a quote against current prices
/quote-store/quotes/{reference}/revalidateParameters
| Name | In | Required | Notes |
|---|---|---|---|
reference | path | yes |
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
channel | string | yes |
Response 200
reference, checkedAt, seen and current versions, differences, differencesHash, lines, totals and acceptable.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 400 | channel_required | The channel query parameter is required to read a quote. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 404 | quote_not_found | The quote does not exist. |
| 404 | quote_store_not_enabled | The quote store is not enabled for the tenant. |
| 409 | quote_not_open | The quote is no longer open. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |