From 99f4aacfac1b5a7e87479d2c6e55992941aca527 Mon Sep 17 00:00:00 2001 From: Julian Maurer Date: Wed, 23 Sep 2026 13:14:22 +0200 Subject: [PATCH] chore(pricing-client): Update Pricing client to latest API specs --- clients/pricing-client/package.json | 2 +- clients/pricing-client/src/openapi.d.ts | 12535 +++++++++++++++++----- clients/pricing-client/src/openapi.json | 5029 +++++++-- 3 files changed, 13972 insertions(+), 3594 deletions(-) diff --git a/clients/pricing-client/package.json b/clients/pricing-client/package.json index ede5588e..c85fdff4 100644 --- a/clients/pricing-client/package.json +++ b/clients/pricing-client/package.json @@ -1,6 +1,6 @@ { "name": "@epilot/pricing-client", - "version": "3.59.0", + "version": "3.59.1", "description": "Client for epilot Pricing APIs", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/clients/pricing-client/src/openapi.d.ts b/clients/pricing-client/src/openapi.d.ts index 8fddb7ac..14278648 100644 --- a/clients/pricing-client/src/openapi.d.ts +++ b/clients/pricing-client/src/openapi.d.ts @@ -169,41 +169,20 @@ declare namespace Components { } export interface AppendVersionRequest { /** - * When this version takes effect. Defaults to now. + * When this version takes effect. Omit it to mean now; a timestamp read from the caller's + * own clock is already a backdate by the time the server judges it, and earns a warning. * - * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time - * (`2026-01-01T00:00:00Z`), to at most millisecond precision. Deliberately not declared as - * `format: date-time`, which would reject the plain-date form that this accepts. - * - * A date in the past is accepted and answered with warnings, never refused. A date the - * variant already has a version at is refused as `VERSION_CONFLICT`. - * - * **Omit this to mean "now"** — that is the only spelling of now that is reliably silent. A - * timestamp taken from the caller's own clock is already some milliseconds old when the - * server judges it, which makes it a backdate, however small, and it is answered with the - * warnings a backdate earns. + * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most + * millisecond precision. A date in the past is accepted; one the variant already has a + * version at is `VERSION_CONFLICT`. * * example: * 2027-01-01T00:00:00Z */ valid_from?: string; - values: /** - * The attribute values this version overrides on the base entity, keyed by attribute name. - * - * Only attributes currently declaring `overridable_attribute` are applied. Metadata fields - * (anything underscore-prefixed), readonly attributes, hidden attributes and non-overridable - * attributes present here are ignored rather than rejected, so a client working from a slightly - * stale schema snapshot still succeeds instead of failing on fields it could not have known to - * drop. An attribute's `render_condition` says when to show it and has no bearing on whether a - * variant may override it. - * - * Ignored means *not updated*, never *removed*: a value already stored for an attribute that is - * not currently overridable is preserved, so removing and restoring the flag deactivates and - * then reactivates the same override. - * - * A composite price's `price_components` is an ordinary overridable relation attribute: a - * composite variant pins its component variants here the same way any other relation value is - * set, with no special handling. + /** + * The overrides this version carries. Attributes the variant may not override are seeded + * from the version in effect at this version's own `valid_from`. * * example: * { @@ -211,11 +190,12 @@ declare namespace Components { * "unit_amount_decimal": "24.99" * } */ - VariantValues; + values: { + [name: string]: any; + }; /** - * Optional, and never applied: a variant's conditions are fixed when it is created. Accepted - * only so that a client building its body from the version it loaded is not forced to strip - * them out, and refused when they describe a different situation from the stored one. + * Accepted only unchanged, so a client can send back the body it loaded. A variant's + * conditions are fixed when it is created. * * example: * { @@ -525,6 +505,12 @@ declare namespace Components { * The flag for prices that contain price components. */ is_composite_price: true; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * The price creation date */ @@ -606,6 +592,12 @@ declare namespace Components { Currency; cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; active?: boolean; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Whether the coupon requires a promo code to be applied */ @@ -952,6 +944,12 @@ declare namespace Components { price_options?: { $relation?: EntityRelation[]; }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Stores references to the availability files that define where this product is available. * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. @@ -1292,6 +1290,12 @@ declare namespace Components { price_options?: { $relation?: EntityRelation[]; }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Stores references to the availability files that define where this product is available. * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. @@ -1512,6 +1516,12 @@ declare namespace Components { price_options?: { $relation?: EntityRelation[]; }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Stores references to the availability files that define where this product is available. * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. @@ -1607,479 +1617,5209 @@ declare namespace Components { */ base_url?: string; } - export type BillingPeriod = "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly"; /** - * A valid cart payload from a client. + * A delete addressing its variant by the situation it applies to. + * + * `conditions` is optional because the fallback variant pins nothing: address it with + * `default: true` and no `conditions`. An item that ends up addressing no variant at all is a + * per-item `VARIANT_UNPINNED`, and one marking `default` beside `conditions` is refused per + * item with no code. + * */ - export interface CartDto { - metadata?: /* A set of key-value pairs used to store meta data information about an entity. */ MetaData; - customer?: Customer; - billing_address?: Address; - delivery_address?: Address; - /** - * type of source, e.g. journey or manual - * example: - * journey - */ - source_type?: string; + export interface BatchDeleteByConditions { /** - * identifier for source e.g. journey ID + * The conditional entity the variant belongs to. * example: - * ce99875f-fba9-4fe2-a8f9-afaf52059051 + * price-sp26d1yo */ - source_id?: string; - source?: /* The order generation source */ OrderSource; - additional_addresses?: Address[]; - payment_method?: /** - * A PaymentMethod represent your customer's payment instruments. + entity_id: string; + conditions?: /** + * The situation this variant applies to: a flat map keyed by condition name. A condition left + * out is a wildcard, which is what makes adding a condition to a schema non-breaking for + * existing variants. + * + * Exact values only; predicates belong to reads. Values are stored canonicalized for their + * type: a `date` becomes millisecond-precision UTC, a `daterange` an object carrying `from` + * and `until` where an empty string is an open end, a `location` of format `zipcode` the + * postal code itself and one of format `zipcode_town` an object carrying both. * + * `default` and names beginning with `_` are reserved; use the request's `default` flag. + * + * example: + * { + * "postal_code": "46045" + * } */ - PaymentMethod; - line_items: /* A valid set of product prices, quantities, (discounts) and taxes from a client. */ PriceItemsDto; + PinnedConditions; /** - * An array of file IDs, already upload into the File API, that are related with this cart + * Address the entity's fallback variant, the one served when nothing else applies. */ - files?: string[]; - status?: /** - * - * | status | description | - * |-------------|-------| - * | `draft` | ​​Starting state for all orders, at this point we can still edit the order | - * | `quote` | The order is in a quoting phase, bound to an expiration date | - * | `placed` | The order has been paid and can now be fulfilled (shipped, delivered, complete) or canceled | - * | `cancelled` | The order has been cancelled | - * | `completed` | The order is now closed and finalized | + default?: boolean; + /** + * The one version to remove, by the instant it takes effect. Omitted, the whole variant + * goes. An RFC 3339 date or date-time, canonicalized before it is matched. * + * example: + * 2027-01-01T00:00:00Z */ - OrderStatus; - tags?: string[]; - journey_data?: { - [name: string]: any; - }; - consents?: { - [name: string]: any; - }; + valid_from?: string; } /** - * A detail associated with a specific cashback. + * A delete addressing its variant by id. */ - export interface CashbackAmount { + export interface BatchDeleteByVariantId { /** - * The name of the cashback. + * The conditional entity the variant belongs to. Required: a variant id alone addresses nothing. + * example: + * price-sp26d1yo */ - cashback_name?: string; - cashback_period: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; + entity_id: string; /** - * The sum of all cashbacks for a specific cashback period + * The variant to remove, or whose version to remove. + * example: + * var-46045 */ - amount_total: number; - } - export interface CashbackAmounts { + variant_id: string; /** - * The cashback amount. + * The one version to remove, by the instant it takes effect. Omitted, the whole variant + * goes. An RFC 3339 date or date-time, canonicalized before it is matched. + * + * example: + * 2027-01-01T00:00:00Z */ - cashback_amount?: number; + valid_from?: string; + } + /** + * How many items reached each outcome. Keyed by exactly the values of `BatchDeleteOutcome`, + * all present, and summing to the length of `results`. + * + */ + export interface BatchDeleteCounts { /** - * The cashback amount as a string with all the decimal places. + * example: + * 1 */ - cashback_amount_decimal?: string; - cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; + deleted: number; /** - * Total amount after cashback is applied. + * example: + * 1 */ - after_cashback_amount_total?: number; + skipped: number; /** - * Total amount after cashback is applied as a string with all the decimal places. + * example: + * 1 */ - after_cashback_amount_total_decimal?: string; + error: number; } /** - * The cashback period, for now it's limited to either 0 months or 12 months + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * */ - export type CashbackPeriod = "0" | "12"; + export type BatchDeleteItem = /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + /* A delete addressing its variant by id. */ BatchDeleteByVariantId | /** + * A delete addressing its variant by the situation it applies to. + * + * `conditions` is optional because the fallback variant pins nothing: address it with + * `default: true` and no `conditions`. An item that ends up addressing no variant at all is a + * per-item `VARIANT_UNPINNED`, and one marking `default` beside `conditions` is refused per + * item with no code. + * + */ + BatchDeleteByConditions; /** - * List of entity fields to include or exclude from the results. + * What one delete item did. + * + * - `deleted`: the variant, or the one version the item named, is gone + * - `skipped`: the item addressed no such variant or version; a missing entity is an `error` + * - `error`: this item alone failed, and the entry's `error` says why * - * example: - * [ - * "!_files", - * "!**.versions" - * ] */ - export type CatalogFieldsParam = string[]; + export type BatchDeleteOutcome = "deleted" | "skipped" | "error"; /** - * A catalog search payload - * example: - * { - * "q": "_id:1233432 OR _id:123432454 OR _id:23445433", - * "sort": "description ASC", - * "from": 0, - * "size": 200 - * } + * What a batch delete did: one entry per item, in request order, and a count per outcome. */ - export interface CatalogSearch { + export interface BatchDeleteResult { /** - * The query to perform using lucene query syntax. + * The `correlation_id` the request carried, echoed only when it was sent. + * example: + * postal-code-cleanup-2026-09 */ - q: string; - /** - * The sort expression to sort the results. + correlation_id?: string; + counts: /** + * How many items reached each outcome. Keyed by exactly the values of `BatchDeleteOutcome`, + * all present, and summing to the length of `results`. + * */ - sort?: string; + BatchDeleteCounts; /** - * The index from which to query, used for pagination purposes. Defaults to 0 + * One entry per item, in request order, which is what maps an outcome back to its source row. */ - from?: number; + results: /* What one delete item did. Position in `results` maps it back to its source row. */ BatchDeleteResultEntry[]; + } + /** + * What one delete item did. Position in `results` maps it back to its source row. + */ + export interface BatchDeleteResultEntry { + outcome: /** + * What one delete item did. + * + * - `deleted`: the variant, or the one version the item named, is gone + * - `skipped`: the item addressed no such variant or version; a missing entity is an `error` + * - `error`: this item alone failed, and the entry's `error` says why + * + */ + BatchDeleteOutcome; /** - * The max size of the response, defaults to 2000. + * The entity this item removed from, echoed from the item. + * example: + * price-sp26d1yo */ - size?: number; + entity_id: string; /** - * When true, enables entity hydration to resolve nested $relation references in-place. + * The variant this item removed, or whose version it removed. Present wherever it is + * known, so a `skipped` entry for a tuple no variant pins names none. + * + * example: + * var-46045 */ - hydrate?: boolean; - fields?: /** - * List of entity fields to include or exclude from the results. + variant_id?: string; + /** + * The version this item removed, canonicalized to millisecond-precision UTC. Absent where + * the item removed the whole variant. * * example: - * [ - * "!_files", - * "!**.versions" - * ] + * 2027-01-01T00:00:00.000Z */ - CatalogFieldsParam; - availability?: /* Availability filters dimensions */ AvailabilityFilters; - } - /** - * The query result payload - * example: - * { - * "hits": 2, - * "results": [ - * { - * "schema": "product", - * "description": "product a" - * }, - * { - * "schema": "price", - * "unit_amount_decimal": "124.342343434" - * } - * ] - * } - */ - export interface CatalogSearchResult { + valid_from?: string; /** - * The number of results returned. + * Things worth knowing that did not stop this item's delete, chiefly which reads the + * removal moved. Always present and possibly empty, on every outcome. + * */ - hits?: number; - results?: (/** - * The product entity - * example: - * { - * "type": "product", - * "_schema": "product", - * "_title": "Solar Panel with Battery Storage", - * "name": "Solar Panel with Battery Storage", - * "code": "SOLAR-BATT", - * "active": true, - * "description": "Solar Panel with battery solution, optimized for max efficiency. ", - * "feature": [ - * { - * "_tags": [], - * "feature": "Eco-Panels" - * }, - * { - * "_tags": [], - * "feature": "Remote Management Platform" - * }, - * { - * "_tags": [], - * "feature": "Battery Remote Control" - * }, - * { - * "_tags": [], - * "feature": "Mobile App" - * } - * ], - * "cross_sellable_products": { - * "$relation": [ - * { - * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", - * "_schema": "product", - * "_tags": [] - * }, - * { - * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", - * "_tags": [] - * } - * ] - * }, - * "product_images": { - * "$relation": [ - * { - * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" - * }, - * { - * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" - * } - * ] - * }, - * "product_downloads": { - * "$relation": [ - * { - * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" - * } - * ] - * }, - * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", - * "_org": "728", - * "_created_at": "2022-06-03T15: 52: 27.512Z", - * "_updated_at": "2022-06-03T16: 05: 15.029Z", - * "price_options": { - * "$relation": [ - * { - * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", - * "_tags": [] - * }, - * { - * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", - * "_tags": [] - * } - * ] - * } - * } + warnings: /** + * Something worth knowing that did not stop a write. One vocabulary for every write; `details` + * is typed per `code`, and a write raises each code at most once. + * */ - Product | /** - * The price entity schema for simple pricing - * example: - * { - * "unit_amount": 100000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "1000", - * "sales_tax": "standard", - * "is_tax_inclusive": true, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "_schema": "price", - * "_title": "Solar Panel Module", - * "description": "Solar Panel Module", - * "active": true, - * "_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", - * "_org": "728", - * "_created_at": "2022-06-03T16:04:10.369Z", - * "_updated_at": "2022-06-03T16:04:10.369Z", - * "pricing_model": "per_unit", - * "is_composite_price": false - * } + WriteWarning[]; + /** + * Why this item failed, present only with `outcome: error`: + * `LAST_VERSION_UNDELETABLE`, `VARIANT_UNPINNED`, the codes a condition tuple that cannot + * be canonicalized raises, `IDENTIFIER_INVALID`, `VALID_FROM_INVALID`, `WRITE_CONFLICT`, + * and the per-item `ENTITY_NOT_FOUND`, `ENTITY_TYPE_MISMATCH` and + * `ENTITY_NOT_CONDITIONAL`. A missing variant or version is `skipped` instead. + * */ - Price | /** - * The coupon entity - * example: - * { - * "_id": "123e4567-e89b-12d3-a456-426614174000", - * "_schema": "coupon", - * "_org": "org_12345", - * "_created_at": "2024-01-15T10:00:00.000Z", - * "_updated_at": "2024-01-20T12:00:00.000Z", - * "_title": "Sample Coupon", - * "name": "Sample Coupon", - * "type": "fixed", - * "fixed_value": 555, - * "fixed_value_currency": "USD", - * "fixed_value_decimal": "5.55", - * "active": true, - * "category": "cashback", - * "prices": { - * "$relation": [ - * { - * "entity_id": "abc12345-def6-7890-gh12-ijklmnopqrst", - * "_tags": [ - * "discount", - * "special" - * ], - * "_schema": "price" - * } - * ] - * } - * } + error?: /** + * Why this item failed, present only with `outcome: error`: + * `LAST_VERSION_UNDELETABLE`, `VARIANT_UNPINNED`, the codes a condition tuple that cannot + * be canonicalized raises, `IDENTIFIER_INVALID`, `VALID_FROM_INVALID`, `WRITE_CONFLICT`, + * and the per-item `ENTITY_NOT_FOUND`, `ENTITY_TYPE_MISMATCH` and + * `ENTITY_NOT_CONDITIONAL`. A missing variant or version is `skipped` instead. + * */ - Coupon)[]; - } - /** - * The cart checkout request payload - */ - export interface CheckoutCart { - cart?: string | /* A valid cart payload from a client. */ CartDto; - redeemed_promos?: RedeemedPromo[]; - mode?: /* The checkout mode for the cart checkout. */ CheckoutMode; - } - /** - * The cart checkout result - */ - export interface CheckoutCartResult { - order?: /** - * The order entity - * example: - * { - * "order_number": "OR 2022/742701", - * "status": "quote", - * "source": { - * "title": "manual", - * "href": null - * }, - * "source_type": "manual", - * "_schema": "order", - * "_title": "OR 2022/742701", - * "expires_at": "2022-06-30T16:17:00.000Z", - * "line_items": [ - * { - * "price_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", - * "product_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", - * "pricing_model": "per_unit", - * "is_composite_price": false, - * "taxes": [ - * { - * "tax": { - * "_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc", - * "rate": 19, - * "_schema": "tax", - * "_org": "728", - * "_created_at": "2021-09-24T15:06:13.859Z", - * "_updated_at": "2022-04-04T17:36:15.273Z", - * "_title": "Tax Standard", - * "type": "VAT", - * "active": true, - * "region": "DE", - * "description": "Standard" - * }, - * "amount": 255462 - * } - * ], - * "_price": { - * "_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", - * "unit_amount": 100000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "1000", - * "sales_tax": "standard", - * "is_tax_inclusive": true, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "_schema": "price", - * "_title": "Solar Panel Module", - * "description": "Solar Panel Module", - * "active": true, - * "pricing_model": "per_unit", - * "is_composite_price": false, - * "tax": { - * "$relation": [ - * { - * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" - * } - * ] - * }, - * "_org": "728", - * "_created_at": "2022-06-03T16:04:10.369Z", - * "_updated_at": "2022-06-03T16:04:10.369Z" - * }, - * "_product": { - * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", - * "type": "product", - * "_schema": "product", - * "_title": "Solar Panel with Battery Storage", - * "name": "Solar Panel with Battery Storage", - * "code": "SOLAR-BATT", - * "active": true, - * "description": "Solar Panel with battery solution, optimized for max efficiency. ", - * "feature": [ - * { - * "_tags": [], - * "feature": "Eco-Panels" - * }, - * { - * "_tags": [], - * "feature": "Remote Management Platform" - * }, - * { - * "_tags": [], - * "feature": "Battery Remote Control" - * }, - * { - * "_tags": [], - * "feature": "Mobile App" - * } - * ], - * "cross_sellable_products": { - * "$relation": [ - * { - * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", - * "_schema": "product", - * "_tags": [] - * }, - * { - * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", - * "_tags": [] - * } - * ] - * }, - * "product_images": { - * "$relation": [ - * { - * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" - * }, - * { - * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" - * } - * ] - * }, - * "product_downloads": { - * "$relation": [ - * { - * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" - * } - * ] - * }, - * "_org": "728", - * "_created_at": "2022-06-03T15:52:27.512Z", - * "_updated_at": "2022-06-03T16:05:15.029Z", - * "price_options": { - * "$relation": [ - * { - * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", - * "_tags": [] - * }, - * { - * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", - * "_tags": [] - * } - * ] - * } - * }, - * "quantity": 16, - * "currency": "EUR", - * "description": "Solar Panel Module", - * "unit_amount": 100000, - * "unit_amount_net": 84034, - * "amount_subtotal": 1344538, - * "amount_total": 1600000 - * }, - * { - * "price_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", - * "product_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", - * "pricing_model": "per_unit", - * "is_composite_price": false, - * "taxes": [ - * { - * "tax": { + { + code: "SCHEMA_NOT_FOUND"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_NOT_FOUND"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_TYPE_MISMATCH"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + /** + * The entity type that id belongs to. Where it is a conditional entity type, + * it is the slug to send instead. + * + * example: + * product + */ + actual_schema: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_NOT_CONDITIONAL"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_NOT_FOUND"; + details: { + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VERSION_NOT_FOUND"; + details: { + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the request addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "NO_MATCHES"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the resolve was scoped to. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "NO_ACTIVE_VERSION"; + details: { + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The instant a version in effect was asked for at. + * example: + * 2026-06-01T00:00:00.000Z + */ + as_of: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "AMBIGUOUS_RESOLUTION"; + details: { + /** + * Every variant that applied, each with the conditions it pins. + */ + candidates: [ + { + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }, + { + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }, + ...{ + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }[] + ]; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "TUPLE_CONFLICT"; + details: { + /** + * The variant the write addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The variant already holding the tuple, where the write read it back. + * example: + * var-50667 + */ + conflicting_variant_id?: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VERSION_CONFLICT"; + details: { + /** + * The variant the write addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The instant already claimed by a version of that variant. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNDEFINED"; + details: { + /** + * The condition the request named and the schema does not define. + * example: + * postal_code + */ + condition_name: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_PIN_UNDECLARED"; + details: { + /** + * The condition the variant pins and the schema no longer declares. + * example: + * postal_code + */ + condition_name: string; + /** + * One variant carrying such a pin. + * example: + * var-46045 + */ + variant_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "OPERATOR_UNSUPPORTED"; + details: { + /** + * example: + * postal_code + */ + condition_name: string; + /** + * The type the schema declares that condition with. + * example: + * location + */ + condition_type: string; + /** + * The predicate the context or filter asked for, or `sort` where a listing + * asked to order by a condition whose type has no order. + * + * example: + * between + */ + operator: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "CONTEXT_FORMAT_INVALID"; + details: { + /** + * example: + * postal_code + */ + condition_name: string; + /** + * What a value for that condition has to be, in prose. + * example: + * a postal code + */ + expected: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_VALUE_INVALID"; + details: { + /** + * example: + * segment + */ + condition_name: string; + /** + * The value the write pinned, as it arrived. + * example: + * industrial + */ + value: any; + /** + * The vocabulary as enforced, after any entries this deploy cannot read have + * been dropped. + * + * example: + * [ + * "private", + * "commercial" + * ] + */ + options: [ + string, + ...string[] + ]; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNCONFIGURED"; + details: { + /** + * The condition whose vocabulary is not configured yet. + * example: + * segment + */ + condition_name: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "TOO_MANY_MATCHES"; + details: { + /** + * The most variants one resolve may compose. + * example: + * 100 + */ + limit: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "WRITE_CONFLICT"; + details: { + /** + * The variant the write addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the write addressed, where one was addressed. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from?: string; + /** + * The revision the write required the stored version to still be at. + * example: + * 3 + */ + expected_revision?: number; + /** + * The revision the version is actually at, where the failed write read it back. + * example: + * 4 + */ + current_revision?: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "OFFSET_WINDOW_EXCEEDED"; + details: { + /** + * The offset the request asked for. + * example: + * 24990 + */ + from: number; + /** + * The page size the request asked for, after clamping. + * example: + * 25 + */ + size: number; + /** + * The last row this deploy's index will serve from an offset. + * example: + * 25000 + */ + window: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "CURSOR_INVALID"; + details: { + /** + * Which check the cursor failed, in prose. + * example: + * The cursor was issued for a different sort order + */ + reason: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_LIMIT_REACHED"; + details: { + /** + * Variants this entity already holds. + * example: + * 5000 + */ + variant_count: number; + /** + * Variants this entity may hold. Configurable per deploy. + * example: + * 5000 + */ + cap: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "PIN_FORMAT_INVALID"; + details: { + /** + * example: + * valid_period + */ + condition_name: string; + /** + * The type the schema declares that condition with. + * example: + * daterange + */ + condition_type: string; + /** + * What a pin for that condition has to be, in prose. + * example: + * an object carrying a from and an until date, either may be open + */ + expected: string; + /** + * The value the write pinned, as it arrived. + * example: + * 2027-01-01/2027-12-31 + */ + value: any; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_UNPINNED"; + details: { + /** + * The conditional entity the item addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "LAST_VERSION_UNDELETABLE"; + details: { + /** + * The variant whose last version the delete addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the delete addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNREADABLE"; + details: { + /** + * The condition whose definition this deploy cannot read. + * example: + * delivery_area + */ + condition_name: string; + /** + * Which field of the definition cannot be read, named as the schema spells it. + * example: + * format + */ + unreadable: "format" | "options"; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "SORT_INVALID"; + details: { + /** + * What a `sort` has to be, in prose. + * example: + * conditions.:asc or conditions.:desc, naming a string, select, number or date condition + */ + expected: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "DEFAULT_MARKER_RESERVED"; + details: { + /** + * The marker, spelled as the request spelled it. + * example: + * default + */ + condition_name: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "DEFAULT_VARIANT_PINS_CONDITIONS"; + details: { + /** + * The conditions the write pinned beside the marker. + * example: + * [ + * "postal_code" + * ] + */ + condition_names: string[]; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VALID_FROM_IMMUTABLE"; + details: { + /** + * The version the request addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + addressed: string; + /** + * The instant the body asked for instead, canonicalized. + * example: + * 2027-04-01T00:00:00.000Z + */ + requested: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_CONDITIONS_IMMUTABLE"; + details: { + /** + * The variant whose conditions the write would have changed. + * example: + * var-46045 + */ + variant_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "IDENTIFIER_INVALID"; + details: { + /** + * Which id could not be keyed by, named as the request names it. + * example: + * entity_id + */ + field: "entity_id" | "variant_id"; + /** + * Which of the three checks the id failed, in prose. + * example: + * it carries a character this scheme does not admit + */ + reason: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VALID_FROM_INVALID"; + details: { + /** + * What a `valid_from` has to be, in prose. + * example: + * an RFC 3339 date, optionally with a time to at most millisecond precision and an optional UTC offset + */ + expected: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + code: "VALUE_UNSTORABLE"; + details: { + /** + * Where the value sits, as a dotted path of the request's own keys, with array + * entries by index. + * + * example: + * values.tiers.0.unit_amount + */ + path: string; + /** + * What about the value cannot be stored, in prose. + * example: + * the non-finite number Infinity + */ + reason: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[]; + } | { + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + error?: /** + * The `error` field of an error response: the message, or — where the request failed + * validation before any handler ran — the validation errors themselves. + * + */ + ReportedError; + }; + } + /** + * A batch of variant and version deletes under one schema, each item naming the entity it removes from. + */ + export interface BatchDeleteVariantsRequest { + /** + * An opaque string echoed back verbatim when it was sent, and never interpreted. + * example: + * postal-code-cleanup-2026-09 + */ + correlation_id?: string; + /** + * The deletes to apply, in the order they should apply where two of them address the same + * variant — decided after every condition tuple has been resolved to a variant id. At most + * 100 per call. + * + */ + items: [ + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem?, + /** + * One delete: the variant, addressed by id or by the condition tuple it pins, and optionally + * the one version of it to remove. An item carrying both matches neither branch and is an + * envelope `400`. + * + */ + BatchDeleteItem? + ]; + } + /** + * How many items reached each outcome. Keyed by exactly the values of `BatchUpsertOutcome`, + * all present, and summing to the length of `results`. + * + */ + export interface BatchUpsertCounts { + /** + * example: + * 1 + */ + variant_created: number; + /** + * example: + * 1 + */ + version_created: number; + /** + * example: + * 1 + */ + updated: number; + /** + * example: + * 1 + */ + skipped: number; + /** + * example: + * 1 + */ + error: number; + } + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + export interface BatchUpsertItem { + /** + * The conditional entity this item writes to. + * example: + * price-sp26d1yo + */ + entity_id: string; + conditions?: /** + * The situation this variant applies to: a flat map keyed by condition name. A condition left + * out is a wildcard, which is what makes adding a condition to a schema non-breaking for + * existing variants. + * + * Exact values only; predicates belong to reads. Values are stored canonicalized for their + * type: a `date` becomes millisecond-precision UTC, a `daterange` an object carrying `from` + * and `until` where an empty string is an open end, a `location` of format `zipcode` the + * postal code itself and one of format `zipcode_town` an object carrying both. + * + * `default` and names beginning with `_` are reserved; use the request's `default` flag. + * + * example: + * { + * "postal_code": "46045" + * } + */ + PinnedConditions; + /** + * Mark this variant as the entity's fallback, as a create does. An item that pins nothing + * and is not the default is `VARIANT_UNPINNED`. + * + */ + default?: boolean; + /** + * When the version this item writes takes effect. Omitted, it is a last-write-wins write + * with no `skipped` detection; a past instant is accepted and reported in this item's + * `warnings`. + * + * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most + * millisecond precision. + * + * example: + * 2027-01-01T00:00:00Z + */ + valid_from?: string; + values: /** + * The values this version overrides on the base entity, keyed by entity field name. + * + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. + * + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. + * + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. + * + * example: + * { + * "unit_amount": 2499, + * "unit_amount_decimal": "24.99" + * } + */ + VariantValues; + } + /** + * What one upsert item did, derived from what was stored. + * + * - `variant_created`: the condition tuple was unknown, so a variant and its first version + * were created + * - `version_created`: the tuple was known and had no version at the item's `valid_from` + * - `updated`: a version existed at that exact instant and was written in place + * - `skipped`: the values are identical to what is stored; not detected for an item without + * `valid_from` + * - `error`: this item alone failed, and the entry's `error` says why + * + */ + export type BatchUpsertOutcome = "variant_created" | "version_created" | "updated" | "skipped" | "error"; + /** + * What a batch upsert did: one entry per item, in request order, and a count per outcome. + */ + export interface BatchUpsertResult { + /** + * The `correlation_id` the request carried, echoed only when it was sent. + * example: + * tariff-refresh-2027-01 + */ + correlation_id?: string; + counts: /** + * How many items reached each outcome. Keyed by exactly the values of `BatchUpsertOutcome`, + * all present, and summing to the length of `results`. + * + */ + BatchUpsertCounts; + /** + * One entry per item, in request order, which is what maps an outcome back to its source row. + */ + results: /* What one upsert item did. Position in `results` maps it back to its source row. */ BatchUpsertResultEntry[]; + } + /** + * What one upsert item did. Position in `results` maps it back to its source row. + */ + export interface BatchUpsertResultEntry { + outcome: /** + * What one upsert item did, derived from what was stored. + * + * - `variant_created`: the condition tuple was unknown, so a variant and its first version + * were created + * - `version_created`: the tuple was known and had no version at the item's `valid_from` + * - `updated`: a version existed at that exact instant and was written in place + * - `skipped`: the values are identical to what is stored; not detected for an item without + * `valid_from` + * - `error`: this item alone failed, and the entry's `error` says why + * + */ + BatchUpsertOutcome; + /** + * The entity this item wrote to, echoed from the item. + * example: + * price-sp26d1yo + */ + entity_id: string; + /** + * The variant this item created or wrote to. Present on every outcome but `error`. + * example: + * var-46045 + */ + variant_id?: string; + /** + * The version this item wrote, canonicalized to millisecond-precision UTC. Present on + * every outcome but `error`, including for an item that sent none. + * + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from?: string; + /** + * Things worth knowing that did not stop this item's write. Always present and possibly + * empty, on every outcome. Fires per item, with no batch-level deduplication. + * + */ + warnings: /** + * Something worth knowing that did not stop a write. One vocabulary for every write; `details` + * is typed per `code`, and a write raises each code at most once. + * + */ + WriteWarning[]; + /** + * Why this item failed, present only with `outcome: error`: the codes a variant create + * raises, plus `ENTITY_NOT_FOUND`, `ENTITY_TYPE_MISMATCH` and `ENTITY_NOT_CONDITIONAL`, + * which are per item because each item names its own entity. Never `TUPLE_CONFLICT` or + * `VERSION_CONFLICT`. + * + */ + error?: /** + * Why this item failed, present only with `outcome: error`: the codes a variant create + * raises, plus `ENTITY_NOT_FOUND`, `ENTITY_TYPE_MISMATCH` and `ENTITY_NOT_CONDITIONAL`, + * which are per item because each item names its own entity. Never `TUPLE_CONFLICT` or + * `VERSION_CONFLICT`. + * + */ + { + code: "SCHEMA_NOT_FOUND"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_NOT_FOUND"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_TYPE_MISMATCH"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + /** + * The entity type that id belongs to. Where it is a conditional entity type, + * it is the slug to send instead. + * + * example: + * product + */ + actual_schema: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_NOT_CONDITIONAL"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_NOT_FOUND"; + details: { + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VERSION_NOT_FOUND"; + details: { + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the request addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "NO_MATCHES"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the resolve was scoped to. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "NO_ACTIVE_VERSION"; + details: { + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The instant a version in effect was asked for at. + * example: + * 2026-06-01T00:00:00.000Z + */ + as_of: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "AMBIGUOUS_RESOLUTION"; + details: { + /** + * Every variant that applied, each with the conditions it pins. + */ + candidates: [ + { + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }, + { + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }, + ...{ + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }[] + ]; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "TUPLE_CONFLICT"; + details: { + /** + * The variant the write addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The variant already holding the tuple, where the write read it back. + * example: + * var-50667 + */ + conflicting_variant_id?: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VERSION_CONFLICT"; + details: { + /** + * The variant the write addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The instant already claimed by a version of that variant. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNDEFINED"; + details: { + /** + * The condition the request named and the schema does not define. + * example: + * postal_code + */ + condition_name: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_PIN_UNDECLARED"; + details: { + /** + * The condition the variant pins and the schema no longer declares. + * example: + * postal_code + */ + condition_name: string; + /** + * One variant carrying such a pin. + * example: + * var-46045 + */ + variant_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "OPERATOR_UNSUPPORTED"; + details: { + /** + * example: + * postal_code + */ + condition_name: string; + /** + * The type the schema declares that condition with. + * example: + * location + */ + condition_type: string; + /** + * The predicate the context or filter asked for, or `sort` where a listing + * asked to order by a condition whose type has no order. + * + * example: + * between + */ + operator: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONTEXT_FORMAT_INVALID"; + details: { + /** + * example: + * postal_code + */ + condition_name: string; + /** + * What a value for that condition has to be, in prose. + * example: + * a postal code + */ + expected: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_VALUE_INVALID"; + details: { + /** + * example: + * segment + */ + condition_name: string; + /** + * The value the write pinned, as it arrived. + * example: + * industrial + */ + value: any; + /** + * The vocabulary as enforced, after any entries this deploy cannot read have + * been dropped. + * + * example: + * [ + * "private", + * "commercial" + * ] + */ + options: [ + string, + ...string[] + ]; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNCONFIGURED"; + details: { + /** + * The condition whose vocabulary is not configured yet. + * example: + * segment + */ + condition_name: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "TOO_MANY_MATCHES"; + details: { + /** + * The most variants one resolve may compose. + * example: + * 100 + */ + limit: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "WRITE_CONFLICT"; + details: { + /** + * The variant the write addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the write addressed, where one was addressed. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from?: string; + /** + * The revision the write required the stored version to still be at. + * example: + * 3 + */ + expected_revision?: number; + /** + * The revision the version is actually at, where the failed write read it back. + * example: + * 4 + */ + current_revision?: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "OFFSET_WINDOW_EXCEEDED"; + details: { + /** + * The offset the request asked for. + * example: + * 24990 + */ + from: number; + /** + * The page size the request asked for, after clamping. + * example: + * 25 + */ + size: number; + /** + * The last row this deploy's index will serve from an offset. + * example: + * 25000 + */ + window: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CURSOR_INVALID"; + details: { + /** + * Which check the cursor failed, in prose. + * example: + * The cursor was issued for a different sort order + */ + reason: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_LIMIT_REACHED"; + details: { + /** + * Variants this entity already holds. + * example: + * 5000 + */ + variant_count: number; + /** + * Variants this entity may hold. Configurable per deploy. + * example: + * 5000 + */ + cap: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "PIN_FORMAT_INVALID"; + details: { + /** + * example: + * valid_period + */ + condition_name: string; + /** + * The type the schema declares that condition with. + * example: + * daterange + */ + condition_type: string; + /** + * What a pin for that condition has to be, in prose. + * example: + * an object carrying a from and an until date, either may be open + */ + expected: string; + /** + * The value the write pinned, as it arrived. + * example: + * 2027-01-01/2027-12-31 + */ + value: any; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_UNPINNED"; + details: { + /** + * The conditional entity the item addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "LAST_VERSION_UNDELETABLE"; + details: { + /** + * The variant whose last version the delete addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the delete addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNREADABLE"; + details: { + /** + * The condition whose definition this deploy cannot read. + * example: + * delivery_area + */ + condition_name: string; + /** + * Which field of the definition cannot be read, named as the schema spells it. + * example: + * format + */ + unreadable: "format" | "options"; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "SORT_INVALID"; + details: { + /** + * What a `sort` has to be, in prose. + * example: + * conditions.:asc or conditions.:desc, naming a string, select, number or date condition + */ + expected: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "DEFAULT_MARKER_RESERVED"; + details: { + /** + * The marker, spelled as the request spelled it. + * example: + * default + */ + condition_name: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "DEFAULT_VARIANT_PINS_CONDITIONS"; + details: { + /** + * The conditions the write pinned beside the marker. + * example: + * [ + * "postal_code" + * ] + */ + condition_names: string[]; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VALID_FROM_IMMUTABLE"; + details: { + /** + * The version the request addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + addressed: string; + /** + * The instant the body asked for instead, canonicalized. + * example: + * 2027-04-01T00:00:00.000Z + */ + requested: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_CONDITIONS_IMMUTABLE"; + details: { + /** + * The variant whose conditions the write would have changed. + * example: + * var-46045 + */ + variant_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "IDENTIFIER_INVALID"; + details: { + /** + * Which id could not be keyed by, named as the request names it. + * example: + * entity_id + */ + field: "entity_id" | "variant_id"; + /** + * Which of the three checks the id failed, in prose. + * example: + * it carries a character this scheme does not admit + */ + reason: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VALID_FROM_INVALID"; + details: { + /** + * What a `valid_from` has to be, in prose. + * example: + * an RFC 3339 date, optionally with a time to at most millisecond precision and an optional UTC offset + */ + expected: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VALUE_UNSTORABLE"; + details: { + /** + * Where the value sits, as a dotted path of the request's own keys, with array + * entries by index. + * + * example: + * values.tiers.0.unit_amount + */ + path: string; + /** + * What about the value cannot be stored, in prose. + * example: + * the non-finite number Infinity + */ + reason: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + error?: /** + * The `error` field of an error response: the message, or — where the request failed + * validation before any handler ran — the validation errors themselves. + * + */ + ReportedError; + }; + } + /** + * A batch of variant writes under one schema, each item naming the entity it writes to. + */ + export interface BatchUpsertVariantsRequest { + /** + * An opaque string echoed back verbatim when it was sent, and never interpreted. + * example: + * tariff-refresh-2027-01 + */ + correlation_id?: string; + /** + * The writes to apply, in the order they should apply where two of them address the same + * variant. At most 100 per call, which is distinct from the per-entity variant cap. + * + */ + items: [ + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem?, + /** + * One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An + * existing condition tuple appends a version to the variant holding it rather than conflicting. + * + */ + BatchUpsertItem? + ]; + } + export type BillingPeriod = "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly"; + /** + * A valid cart payload from a client. + */ + export interface CartDto { + metadata?: /* A set of key-value pairs used to store meta data information about an entity. */ MetaData; + customer?: Customer; + billing_address?: Address; + delivery_address?: Address; + /** + * type of source, e.g. journey or manual + * example: + * journey + */ + source_type?: string; + /** + * identifier for source e.g. journey ID + * example: + * ce99875f-fba9-4fe2-a8f9-afaf52059051 + */ + source_id?: string; + source?: /* The order generation source */ OrderSource; + additional_addresses?: Address[]; + payment_method?: /** + * A PaymentMethod represent your customer's payment instruments. + * + */ + PaymentMethod; + line_items: /* A valid set of product prices, quantities, (discounts) and taxes from a client. */ PriceItemsDto; + /** + * An array of file IDs, already upload into the File API, that are related with this cart + */ + files?: string[]; + status?: /** + * + * | status | description | + * |-------------|-------| + * | `draft` | ​​Starting state for all orders, at this point we can still edit the order | + * | `quote` | The order is in a quoting phase, bound to an expiration date | + * | `placed` | The order has been paid and can now be fulfilled (shipped, delivered, complete) or canceled | + * | `cancelled` | The order has been cancelled | + * | `completed` | The order is now closed and finalized | + * + */ + OrderStatus; + tags?: string[]; + journey_data?: { + [name: string]: any; + }; + consents?: { + [name: string]: any; + }; + } + /** + * A detail associated with a specific cashback. + */ + export interface CashbackAmount { + /** + * The name of the cashback. + */ + cashback_name?: string; + cashback_period: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; + /** + * The sum of all cashbacks for a specific cashback period + */ + amount_total: number; + } + export interface CashbackAmounts { + /** + * The cashback amount. + */ + cashback_amount?: number; + /** + * The cashback amount as a string with all the decimal places. + */ + cashback_amount_decimal?: string; + cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; + /** + * Total amount after cashback is applied. + */ + after_cashback_amount_total?: number; + /** + * Total amount after cashback is applied as a string with all the decimal places. + */ + after_cashback_amount_total_decimal?: string; + } + /** + * The cashback period, for now it's limited to either 0 months or 12 months + */ + export type CashbackPeriod = "0" | "12"; + /** + * List of entity fields to include or exclude from the results. + * + * example: + * [ + * "!_files", + * "!**.versions" + * ] + */ + export type CatalogFieldsParam = string[]; + /** + * A catalog search payload + * example: + * { + * "q": "_id:1233432 OR _id:123432454 OR _id:23445433", + * "sort": "description ASC", + * "from": 0, + * "size": 200 + * } + */ + export interface CatalogSearch { + /** + * The query to perform using lucene query syntax. + */ + q: string; + /** + * The sort expression to sort the results. + */ + sort?: string; + /** + * The index from which to query, used for pagination purposes. Defaults to 0 + */ + from?: number; + /** + * The max size of the response, defaults to 2000. + */ + size?: number; + /** + * When true, enables entity hydration to resolve nested $relation references in-place. + */ + hydrate?: boolean; + fields?: /** + * List of entity fields to include or exclude from the results. + * + * example: + * [ + * "!_files", + * "!**.versions" + * ] + */ + CatalogFieldsParam; + availability?: /* Availability filters dimensions */ AvailabilityFilters; + } + /** + * The query result payload + * example: + * { + * "hits": 2, + * "results": [ + * { + * "schema": "product", + * "description": "product a" + * }, + * { + * "schema": "price", + * "unit_amount_decimal": "124.342343434" + * } + * ] + * } + */ + export interface CatalogSearchResult { + /** + * The number of results returned. + */ + hits?: number; + results?: (/** + * The product entity + * example: + * { + * "type": "product", + * "_schema": "product", + * "_title": "Solar Panel with Battery Storage", + * "name": "Solar Panel with Battery Storage", + * "code": "SOLAR-BATT", + * "active": true, + * "description": "Solar Panel with battery solution, optimized for max efficiency. ", + * "feature": [ + * { + * "_tags": [], + * "feature": "Eco-Panels" + * }, + * { + * "_tags": [], + * "feature": "Remote Management Platform" + * }, + * { + * "_tags": [], + * "feature": "Battery Remote Control" + * }, + * { + * "_tags": [], + * "feature": "Mobile App" + * } + * ], + * "cross_sellable_products": { + * "$relation": [ + * { + * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", + * "_schema": "product", + * "_tags": [] + * }, + * { + * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", + * "_tags": [] + * } + * ] + * }, + * "product_images": { + * "$relation": [ + * { + * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" + * }, + * { + * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" + * } + * ] + * }, + * "product_downloads": { + * "$relation": [ + * { + * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" + * } + * ] + * }, + * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", + * "_org": "728", + * "_created_at": "2022-06-03T15: 52: 27.512Z", + * "_updated_at": "2022-06-03T16: 05: 15.029Z", + * "price_options": { + * "$relation": [ + * { + * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", + * "_tags": [] + * }, + * { + * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", + * "_tags": [] + * } + * ] + * } + * } + */ + Product | /** + * The price entity schema for simple pricing + * example: + * { + * "unit_amount": 100000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "1000", + * "sales_tax": "standard", + * "is_tax_inclusive": true, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "_schema": "price", + * "_title": "Solar Panel Module", + * "description": "Solar Panel Module", + * "active": true, + * "_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", + * "_org": "728", + * "_created_at": "2022-06-03T16:04:10.369Z", + * "_updated_at": "2022-06-03T16:04:10.369Z", + * "pricing_model": "per_unit", + * "is_composite_price": false + * } + */ + Price | /** + * The coupon entity + * example: + * { + * "_id": "123e4567-e89b-12d3-a456-426614174000", + * "_schema": "coupon", + * "_org": "org_12345", + * "_created_at": "2024-01-15T10:00:00.000Z", + * "_updated_at": "2024-01-20T12:00:00.000Z", + * "_title": "Sample Coupon", + * "name": "Sample Coupon", + * "type": "fixed", + * "fixed_value": 555, + * "fixed_value_currency": "USD", + * "fixed_value_decimal": "5.55", + * "active": true, + * "category": "cashback", + * "prices": { + * "$relation": [ + * { + * "entity_id": "abc12345-def6-7890-gh12-ijklmnopqrst", + * "_tags": [ + * "discount", + * "special" + * ], + * "_schema": "price" + * } + * ] + * } + * } + */ + Coupon)[]; + } + /** + * The cart checkout request payload + */ + export interface CheckoutCart { + cart?: string | /* A valid cart payload from a client. */ CartDto; + redeemed_promos?: RedeemedPromo[]; + mode?: /* The checkout mode for the cart checkout. */ CheckoutMode; + } + /** + * The cart checkout result + */ + export interface CheckoutCartResult { + order?: /** + * The order entity + * example: + * { + * "order_number": "OR 2022/742701", + * "status": "quote", + * "source": { + * "title": "manual", + * "href": null + * }, + * "source_type": "manual", + * "_schema": "order", + * "_title": "OR 2022/742701", + * "expires_at": "2022-06-30T16:17:00.000Z", + * "line_items": [ + * { + * "price_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", + * "product_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", + * "pricing_model": "per_unit", + * "is_composite_price": false, + * "taxes": [ + * { + * "tax": { + * "_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc", + * "rate": 19, + * "_schema": "tax", + * "_org": "728", + * "_created_at": "2021-09-24T15:06:13.859Z", + * "_updated_at": "2022-04-04T17:36:15.273Z", + * "_title": "Tax Standard", + * "type": "VAT", + * "active": true, + * "region": "DE", + * "description": "Standard" + * }, + * "amount": 255462 + * } + * ], + * "_price": { + * "_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", + * "unit_amount": 100000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "1000", + * "sales_tax": "standard", + * "is_tax_inclusive": true, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "_schema": "price", + * "_title": "Solar Panel Module", + * "description": "Solar Panel Module", + * "active": true, + * "pricing_model": "per_unit", + * "is_composite_price": false, + * "tax": { + * "$relation": [ + * { + * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" + * } + * ] + * }, + * "_org": "728", + * "_created_at": "2022-06-03T16:04:10.369Z", + * "_updated_at": "2022-06-03T16:04:10.369Z" + * }, + * "_product": { + * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", + * "type": "product", + * "_schema": "product", + * "_title": "Solar Panel with Battery Storage", + * "name": "Solar Panel with Battery Storage", + * "code": "SOLAR-BATT", + * "active": true, + * "description": "Solar Panel with battery solution, optimized for max efficiency. ", + * "feature": [ + * { + * "_tags": [], + * "feature": "Eco-Panels" + * }, + * { + * "_tags": [], + * "feature": "Remote Management Platform" + * }, + * { + * "_tags": [], + * "feature": "Battery Remote Control" + * }, + * { + * "_tags": [], + * "feature": "Mobile App" + * } + * ], + * "cross_sellable_products": { + * "$relation": [ + * { + * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", + * "_schema": "product", + * "_tags": [] + * }, + * { + * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", + * "_tags": [] + * } + * ] + * }, + * "product_images": { + * "$relation": [ + * { + * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" + * }, + * { + * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" + * } + * ] + * }, + * "product_downloads": { + * "$relation": [ + * { + * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" + * } + * ] + * }, + * "_org": "728", + * "_created_at": "2022-06-03T15:52:27.512Z", + * "_updated_at": "2022-06-03T16:05:15.029Z", + * "price_options": { + * "$relation": [ + * { + * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", + * "_tags": [] + * }, + * { + * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", + * "_tags": [] + * } + * ] + * } + * }, + * "quantity": 16, + * "currency": "EUR", + * "description": "Solar Panel Module", + * "unit_amount": 100000, + * "unit_amount_net": 84034, + * "amount_subtotal": 1344538, + * "amount_total": 1600000 + * }, + * { + * "price_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", + * "product_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", + * "pricing_model": "per_unit", + * "is_composite_price": false, + * "taxes": [ + * { + * "tax": { * "_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc", * "rate": 19, * "_schema": "tax", @@ -2762,1614 +7502,3164 @@ declare namespace Components { * } * } */ - NonHydratedCompositePrice | /** - * The composite price entity - * example: - * { - * "_id": "c2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_title": "My Composite Price", - * "description": "My Composite Price", - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "is_composite_price": true, - * "price_components": { - * "$relation": [ - * { - * "entity_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_product_id": "target-price-product-id", - * "quantity": 1, - * "item": { - * "_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "_schema": "price", - * "_title": "Test 1", - * "description": "Test 1", - * "tax": { - * "$relation": [ - * { - * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" - * } - * ] - * }, - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "is_composite_price": false - * } - * }, - * { - * "entity_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_product_id": "target-price-product-id", - * "quantity": 2, - * "item": { - * "_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "_schema": "price", - * "_title": "Test 1", - * "description": "Test 1", - * "tax": { - * "$relation": [ - * { - * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" - * } - * ] - * }, - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "is_composite_price": false - * } - * } - * ] - * } - * } + NonHydratedCompositePrice | /** + * The composite price entity + * example: + * { + * "_id": "c2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_title": "My Composite Price", + * "description": "My Composite Price", + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "is_composite_price": true, + * "price_components": { + * "$relation": [ + * { + * "entity_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_product_id": "target-price-product-id", + * "quantity": 1, + * "item": { + * "_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "_schema": "price", + * "_title": "Test 1", + * "description": "Test 1", + * "tax": { + * "$relation": [ + * { + * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" + * } + * ] + * }, + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "is_composite_price": false + * } + * }, + * { + * "entity_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_product_id": "target-price-product-id", + * "quantity": 2, + * "item": { + * "_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "_schema": "price", + * "_title": "Test 1", + * "description": "Test 1", + * "tax": { + * "$relation": [ + * { + * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" + * } + * ] + * }, + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "is_composite_price": false + * } + * } + * ] + * } + * } + */ + HydratedCompositePrice; + /** + * Represents a composite price input to the pricing library. + * example: + * { + * "amount_subtotal": 10000, + * "amount_total": 10600, + * "currency": "EUR", + * "description": "Annual internet service", + * "price_id": "7e24ff5d-d580-4136-a32f-19191eed039a", + * "product_id": "6241487f-b7fd-428b-ab92-24ee0b37fd84", + * "taxes": [ + * { + * "amount": 600, + * "tax": { + * "active": true, + * "description": "Without Behaviour", + * "rate": 6, + * "region": "DE", + * "type": "VAT", + * "_created_at": "2022-02-07T14:49:08.831Z", + * "_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4", + * "_org": "739224", + * "_schema": "tax", + * "_title": "Tax Without Behaviour", + * "_updated_at": "2022-02-07T14:49:08.831Z" + * } + * } + * ], + * "unit_amount": 10000, + * "unit_amount_net": 10000, + * "pricing_model": "per_unit", + * "_price": { + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "_schema": "price", + * "_title": "Solar Panel Module", + * "description": "Solar Panel Module", + * "active": true, + * "tax": { + * "$relation": [ + * { + * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" + * } + * ] + * }, + * "_id": "7e24ff5d-d580-4136-a32f-19191eed039a", + * "_org": "728", + * "_created_at": "2022-06-03T16:04:10.369Z", + * "_updated_at": "2022-06-03T16:04:10.369Z", + * "pricing_model": "per_unit" + * }, + * "_product": { + * "name": "Cool box", + * "type": "product", + * "_id": "73f857a4-0fbc-4aa6-983f-87c0d6d410a6", + * "_title": "Cool box" + * } + * } + */ + export interface CompositePriceItem { + /** + * Total of all items before (discounts or) taxes are applied. + */ + amount_subtotal?: number; + /** + * Total of all items before (discounts or) taxes are applied, as a string with all the decimal places. + */ + amount_subtotal_decimal?: string; + /** + * Total of all items after (discounts and) taxes are applied. + */ + amount_total?: number; + /** + * Total of all items after (discounts and) taxes are applied, as a string with all the decimal places. + */ + amount_total_decimal?: string; + /** + * The cashback amount. + */ + cashback_amount?: number; + /** + * The cashback amount as a string with all the decimal places. + */ + cashback_amount_decimal?: string; + cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; + /** + * Total amount after cashback is applied. + */ + after_cashback_amount_total?: number; + /** + * Total amount after cashback is applied as a string with all the decimal places. + */ + after_cashback_amount_total_decimal?: string; + /** + * The discount amount. + */ + discount_amount?: number; + /** + * The discount amount as a string with all the decimal places. + */ + discount_amount_decimal?: string; + /** + * The discount percentage, if the applied coupon had a percentage type. + */ + discount_percentage?: number; + /** + * Total amount before discount is applied. + */ + before_discount_amount_total?: number; + /** + * Total amount before discount is applied as a string with all the decimal places. + */ + before_discount_amount_total_decimal?: string; + /** + * Total amount before discount is applied, excluding taxes. + */ + before_discount_amount_subtotal?: number; + /** + * Total amount before discount is applied, excluding taxes, as a string with all the decimal places. + */ + before_discount_amount_subtotal_decimal?: string; + metadata?: /* A set of key-value pairs used to store meta data information about an entity. */ MetaData; + /** + * The quantity of products being purchased. + */ + quantity?: number; + /** + * The id of the product. + */ + product_id?: string; + /** + * The id of the price. + */ + price_id?: string; + /** + * An arbitrary string attached to the price item. Often useful for displaying to users. Defaults to product name. + */ + description?: string; + /** + * The description for the product. + */ + product_description?: string; + /** + * The name for the product. + */ + product_name?: string; + price_mappings?: /** + * example: + * [ + * { + * "price_id": "589B011B-F8D9-4F8E-AD71-BACE4B543C0F", + * "frequency_unit": "weekly", + * "value": 1000.245, + * "name": "avg consumption", + * "metadata": { + * "journey_title": "energy journey", + * "step_name": "avg consumption picker" + * } + * } + * ] + */ + PriceInputMappings; + /** + * Specifies whether the price is considered `inclusive` of taxes or not. + */ + is_tax_inclusive?: boolean; + /** + * The snapshot of the product. + * example: + * { + * "type": "product", + * "_schema": "product", + * "_title": "Solar Panel with Battery Storage", + * "name": "Solar Panel with Battery Storage", + * "code": "SOLAR-BATT", + * "active": true, + * "description": "Solar Panel with battery solution, optimized for max efficiency. ", + * "feature": [ + * { + * "_tags": [], + * "feature": "Eco-Panels" + * }, + * { + * "_tags": [], + * "feature": "Remote Management Platform" + * }, + * { + * "_tags": [], + * "feature": "Battery Remote Control" + * }, + * { + * "_tags": [], + * "feature": "Mobile App" + * } + * ], + * "cross_sellable_products": { + * "$relation": [ + * { + * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", + * "_schema": "product", + * "_tags": [] + * }, + * { + * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", + * "_tags": [] + * } + * ] + * }, + * "product_images": { + * "$relation": [ + * { + * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" + * }, + * { + * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" + * } + * ] + * }, + * "product_downloads": { + * "$relation": [ + * { + * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" + * } + * ] + * }, + * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", + * "_org": "728", + * "_created_at": "2022-06-03T15: 52: 27.512Z", + * "_updated_at": "2022-06-03T16: 05: 15.029Z", + * "price_options": { + * "$relation": [ + * { + * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", + * "_tags": [] + * }, + * { + * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", + * "_tags": [] + * } + * ] + * } + * } + */ + _product?: { + [name: string]: any; + /** + * The description for the product + */ + description?: string; + /** + * The product code + */ + code?: string; + /** + * The type of Product: + * + * | type | description | + * |----| ----| + * | `product` | Represents a physical good | + * | `service` | Represents a service or virtual product | + * + */ + type?: "product" | "service"; + /** + * The product main name + */ + name?: string; + /** + * The product categories + */ + categories?: string[]; + feature?: { + /** + * An arbitrary set of tags attached to a feature + */ + _tags?: string[]; + feature?: string; + }[]; + /** + * Stores references to products that can be cross sold with the current product. + */ + cross_sellable_products?: { + $relation?: EntityRelation[]; + }; + /** + * Stores references to a set of file images of the product + */ + product_images?: /* Stores references to a set of file images of the product */ { + $relation?: EntityRelation[]; + } | File[]; + /** + * Stores references to a set of files downloadable from the product. + * e.g: tech specifications, quality control sheets, privacy policy agreements + * + */ + product_downloads?: /** + * Stores references to a set of files downloadable from the product. + * e.g: tech specifications, quality control sheets, privacy policy agreements + * + */ + { + $relation?: EntityRelation[]; + } | File[]; + /** + * A set of [prices](/api/pricing#tag/simple_price_schema) or [composite prices](/api/pricing#tag/dynamic_price_schema) for the current product. + */ + price_options?: { + $relation?: EntityRelation[]; + }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; + /** + * Stores references to the availability files that define where this product is available. + * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. + * + */ + _availability_files?: File[]; + /** + * The product id + */ + _id?: string; + /** + * The autogenerated product title + */ + _title?: string; + /** + * The organization id the product belongs to + */ + _org_id?: string; + /** + * The product creation date + */ + _created_at?: string; + /** + * The product last update date + */ + _updated_at?: string; + }; + /** + * price item id + */ + _id?: string; + /** + * The unit amount value + */ + unit_amount?: number; + /** + * The unit amount in eur to be charged, represented as a decimal string with at most 12 decimal places. + */ + unit_amount_decimal?: string; + /** + * The unit amount before any discount is applied + */ + before_discount_unit_amount?: number; + /** + * The unit amount before any discount is applied, represented as a decimal string with at most 12 decimal places. + */ + before_discount_unit_amount_decimal?: string; + /** + * The unit gross amount before any discount is applied + */ + before_discount_unit_amount_gross?: number; + /** + * The unit gross amount before any discount is applied, represented as a decimal string with at most 12 decimal places. + */ + before_discount_unit_amount_gross_decimal?: string; + /** + * The unit net amount before any discount is applied + */ + before_discount_unit_amount_net?: number; + /** + * The unit net amount before any discount is applied, represented as a decimal string with at most 12 decimal places. + */ + before_discount_unit_amount_net_decimal?: string; + /** + * The discount amount applied for each unit + */ + unit_discount_amount?: number; + /** + * The discount amount applied for each unit represented as a decimal string + */ + unit_discount_amount_decimal?: string; + /** + * The unit gross amount value. + */ + unit_amount_gross?: number; + /** + * The unit gross amount value. + */ + unit_amount_gross_decimal?: string; + /** + * Net unit amount without taxes or discounts. + */ + unit_amount_net?: number; + /** + * Net unit amount without taxes or discounts. + */ + unit_amount_net_decimal?: string; + /** + * The net discount amount applied for each unit + */ + unit_discount_amount_net?: number; + /** + * The net discount amount applied for each unit represented as a decimal string + */ + unit_discount_amount_net_decimal?: string; + /** + * The discount amount applied to the tax + */ + tax_discount_amount?: number; + /** + * The discount amount applied to the tax represented as a decimal string + */ + tax_discount_amount_decimal?: string; + /** + * The net discount amount applied + */ + discount_amount_net?: number; + /** + * The net discount amount applied represented as a decimal string + */ + discount_amount_net_decimal?: string; + /** + * Total tax amount for this line item. + */ + amount_tax?: number; + /** + * The tax amount before any discount is applied + */ + before_discount_tax_amount?: number; + /** + * The tax amount before any discount is applied represented as a decimal string + */ + before_discount_tax_amount_decimal?: string; + currency?: /** + * Three-letter ISO currency code, in lowercase. Must be a supported currency. + * ISO 4217 CURRENCY CODES as specified in the documentation: https://www.iso.org/iso-4217-currency-codes.html + * + * example: + * EUR + */ + Currency; + /** + * The taxes applied to the price item. + */ + taxes?: (/* A tax amount associated with a specific tax rate. */ TaxAmount)[]; + /** + * The sum of amounts of the price items by recurrence. + */ + recurrences?: (/* An amount associated with a specific recurrence. */ RecurrenceAmount)[]; + /** + * The coupons applicable to the composite price item + related (cashback) amounts + */ + _coupons?: ({ + [name: string]: any; + _id: EntityId /* uuid */; + /** + * The auto-generated title for the title + */ + _title: string; + /** + * Organization Id the entity belongs to + */ + _org: string; + /** + * The schema of the entity, for coupons it is always `coupon` + */ + _schema: "coupon"; + _tags?: string[]; + /** + * The creation date for the opportunity + */ + _created_at: string; // date-time + /** + * The date the coupon was last updated + */ + _updated_at: string; // date-time + name: string | null; + description?: string | null; + type: "fixed" | "percentage"; + category: "discount" | "cashback"; + /** + * Use if type is set to percentage. The percentage to be discounted, represented as a whole integer. + */ + percentage_value?: string | null; + /** + * Use if type is set to fixed. The fixed amount in cents to be discounted, represented as a whole integer. + */ + fixed_value?: number; + /** + * Use if type is set to fixed. The unit amount in eur to be discounted, represented as a decimal string with at most 12 decimal places. + */ + fixed_value_decimal?: string; + /** + * Use if type is set to fixed. Three-letter ISO currency code, in lowercase. + */ + fixed_value_currency?: /* Use if type is set to fixed. Three-letter ISO currency code, in lowercase. */ /** + * Three-letter ISO currency code, in lowercase. Must be a supported currency. + * ISO 4217 CURRENCY CODES as specified in the documentation: https://www.iso.org/iso-4217-currency-codes.html + * + * example: + * EUR + */ + Currency; + cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; + active?: boolean; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; + /** + * Whether the coupon requires a promo code to be applied + */ + requires_promo_code?: boolean; + /** + * The cashback amount. + */ + cashback_amount?: number; + /** + * The cashback amount as a string with all the decimal places. + */ + cashback_amount_decimal?: string; + /** + * Total amount after cashback is applied. + */ + after_cashback_amount_total?: number; + /** + * Total amount after cashback is applied as a string with all the decimal places. + */ + after_cashback_amount_total_decimal?: string; + } & /* The shared properties for the coupon entity and coupon item entity */ (/* The shared properties for the coupon entity and coupon item entity */ CouponItem))[]; + /** + * When set to true on a `_price` displayed as OnRequest (`show_as_on_request: 'on_request'`) this flag means the price has been approved and can now be displayed to the customer. This flag is only valid for prices shown as 'on_request'. + */ + on_request_approved?: boolean; + /** + * The flag for prices that contain price components. + */ + is_composite_price: true; + /** + * Contains price item configurations, per price component, when the main price item is a [composite price](/api/pricing#tag/dynamic_price_schema). + */ + item_components?: /** + * Represents a price item + * example: + * { + * "amount_subtotal": 10000, + * "amount_total": 10600, + * "currency": "EUR", + * "description": "Annual internet service", + * "price_id": "7e24ff5d-d580-4136-a32f-19191eed039a", + * "product_id": "6241487f-b7fd-428b-ab92-24ee0b37fd84", + * "taxes": [ + * { + * "amount": 600, + * "tax": { + * "active": true, + * "description": "Without Behaviour", + * "rate": 6, + * "region": "DE", + * "type": "VAT", + * "_created_at": "2022-02-07T14:49:08.831Z", + * "_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4", + * "_org": "739224", + * "_schema": "tax", + * "_title": "Tax Without Behaviour", + * "_updated_at": "2022-02-07T14:49:08.831Z" + * } + * }, + * { + * "amount": 600, + * "tax": { + * "active": true, + * "description": "Without Behaviour", + * "rate": 6, + * "region": "DE", + * "type": "VAT", + * "_created_at": "2022-02-07T14:49:08.831Z", + * "_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4", + * "_org": "739224", + * "_schema": "tax", + * "_title": "Tax Without Behaviour", + * "_updated_at": "2022-02-07T14:49:08.831Z" + * } + * } + * ], + * "unit_amount": 10000, + * "unit_amount_net": 10000, + * "pricing_model": "per_unit", + * "_price": { + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "_schema": "price", + * "_title": "Solar Panel Module", + * "description": "Solar Panel Module", + * "active": true, + * "tax": { + * "$relation": [ + * { + * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" + * }, + * { + * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" + * } + * ] + * }, + * "_id": "7e24ff5d-d580-4136-a32f-19191eed039a", + * "_org": "728", + * "_created_at": "2022-06-03T16:04:10.369Z", + * "_updated_at": "2022-06-03T16:04:10.369Z", + * "pricing_model": "per_unit" + * }, + * "_product": { + * "name": "Cool box", + * "type": "product", + * "_id": "73f857a4-0fbc-4aa6-983f-87c0d6d410a6", + * "_title": "Cool box" + * } + * } + */ + PriceItem[]; + total_details?: /* The total details with tax (and discount) aggregated totals. */ TotalDetails; + /** + * The price snapshot data. + */ + _price?: /* The price snapshot data. */ /** + * The composite price entity + * example: + * { + * "_id": "c2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_title": "My Composite Price", + * "description": "My Composite Price", + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "is_composite_price": true, + * "price_components": { + * "$relation": [ + * { + * "entity_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_product_id": "target-price-product-id", + * "quantity": 1, + * "item": { + * "_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "_schema": "price", + * "_title": "Test 1", + * "description": "Test 1", + * "tax": { + * "$relation": [ + * { + * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" + * } + * ] + * }, + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "is_composite_price": false + * } + * }, + * { + * "entity_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_product_id": "target-price-product-id", + * "quantity": 2, + * "item": { + * "_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "_schema": "price", + * "_title": "Test 1", + * "description": "Test 1", + * "tax": { + * "$relation": [ + * { + * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" + * } + * ] + * }, + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "is_composite_price": false + * } + * } + * ] + * } + * } + */ + CompositePrice; + } + /** + * Represents a composite price input to the pricing library. + */ + export interface CompositePriceItemDto { + metadata?: /* A set of key-value pairs used to store meta data information about an entity. */ MetaData; + /** + * The quantity of products being purchased. + */ + quantity?: number; + /** + * The id of the product. + */ + product_id?: string; + /** + * The id of the price. + */ + price_id?: string; + /** + * An arbitrary string attached to the price item. Often useful for displaying to users. Defaults to product name. + */ + description?: string; + /** + * The description for the product. + */ + product_description?: string; + /** + * The name for the product. + */ + product_name?: string; + price_mappings?: /** + * example: + * [ + * { + * "price_id": "589B011B-F8D9-4F8E-AD71-BACE4B543C0F", + * "frequency_unit": "weekly", + * "value": 1000.245, + * "name": "avg consumption", + * "metadata": { + * "journey_title": "energy journey", + * "step_name": "avg consumption picker" + * } + * } + * ] + */ + PriceInputMappings; + /** + * Specifies whether the price is considered `inclusive` of taxes or not. + */ + is_tax_inclusive?: boolean; + /** + * The snapshot of the product. + * example: + * { + * "type": "product", + * "_schema": "product", + * "_title": "Solar Panel with Battery Storage", + * "name": "Solar Panel with Battery Storage", + * "code": "SOLAR-BATT", + * "active": true, + * "description": "Solar Panel with battery solution, optimized for max efficiency. ", + * "feature": [ + * { + * "_tags": [], + * "feature": "Eco-Panels" + * }, + * { + * "_tags": [], + * "feature": "Remote Management Platform" + * }, + * { + * "_tags": [], + * "feature": "Battery Remote Control" + * }, + * { + * "_tags": [], + * "feature": "Mobile App" + * } + * ], + * "cross_sellable_products": { + * "$relation": [ + * { + * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", + * "_schema": "product", + * "_tags": [] + * }, + * { + * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", + * "_tags": [] + * } + * ] + * }, + * "product_images": { + * "$relation": [ + * { + * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" + * }, + * { + * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" + * } + * ] + * }, + * "product_downloads": { + * "$relation": [ + * { + * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" + * } + * ] + * }, + * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", + * "_org": "728", + * "_created_at": "2022-06-03T15: 52: 27.512Z", + * "_updated_at": "2022-06-03T16: 05: 15.029Z", + * "price_options": { + * "$relation": [ + * { + * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", + * "_tags": [] + * }, + * { + * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", + * "_tags": [] + * } + * ] + * } + * } + */ + _product?: { + [name: string]: any; + /** + * The description for the product + */ + description?: string; + /** + * The product code + */ + code?: string; + /** + * The type of Product: + * + * | type | description | + * |----| ----| + * | `product` | Represents a physical good | + * | `service` | Represents a service or virtual product | + * + */ + type?: "product" | "service"; + /** + * The product main name + */ + name?: string; + /** + * The product categories + */ + categories?: string[]; + feature?: { + /** + * An arbitrary set of tags attached to a feature + */ + _tags?: string[]; + feature?: string; + }[]; + /** + * Stores references to products that can be cross sold with the current product. + */ + cross_sellable_products?: { + $relation?: EntityRelation[]; + }; + /** + * Stores references to a set of file images of the product + */ + product_images?: /* Stores references to a set of file images of the product */ { + $relation?: EntityRelation[]; + } | File[]; + /** + * Stores references to a set of files downloadable from the product. + * e.g: tech specifications, quality control sheets, privacy policy agreements + * + */ + product_downloads?: /** + * Stores references to a set of files downloadable from the product. + * e.g: tech specifications, quality control sheets, privacy policy agreements + * + */ + { + $relation?: EntityRelation[]; + } | File[]; + /** + * A set of [prices](/api/pricing#tag/simple_price_schema) or [composite prices](/api/pricing#tag/dynamic_price_schema) for the current product. + */ + price_options?: { + $relation?: EntityRelation[]; + }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; + /** + * Stores references to the availability files that define where this product is available. + * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. + * + */ + _availability_files?: File[]; + /** + * The product id + */ + _id?: string; + /** + * The autogenerated product title + */ + _title?: string; + /** + * The organization id the product belongs to + */ + _org_id?: string; + /** + * The product creation date + */ + _created_at?: string; + /** + * The product last update date + */ + _updated_at?: string; + }; + external_fees_mappings?: /** + * example: + * [ + * { + * "price_id": "589B011B-F8D9-4F8E-AD71-BACE4B543C0F", + * "frequency_unit": "weekly", + * "amount_total": 1000, + * "amount_total_decimal": "10.00" + * } + * ] + */ + ExternalFeeMappings; + external_fees_metadata?: ExternalFeeMetadata; + external_location_metadata?: /* The provider entity */ ExternalLocationMetadata; + external_price_metadata?: ExternalPriceMetadata; + _immutable_pricing_details?: /* The result from the calculation of a set of price items. */ PricingDetails; + /** + * The ids of the coupons applicable to the price item + */ + coupon_ids?: string[]; + /** + * The taxes applied to the price item. + */ + taxes?: (/* A valid tax rate from a client. */ TaxAmountDto)[]; + /** + * The taxes applied to the price item. + */ + recurrences?: (/* An amount associated with a specific recurrence. */ RecurrenceAmountDto)[]; + /** + * The coupons applicable to the price item + */ + _coupons?: (/* The shared properties for the coupon entity and coupon item entity */ CouponItem)[]; + /** + * The flag for prices that contain price components. + */ + is_composite_price: true; + /** + * Contains price item configurations, per price component, when the main price item is a [composite price](/api/pricing#tag/dynamic_price_schema). + */ + item_components?: /* Represents a price input to the pricing library. */ PriceItemDto[]; + /** + * The ids of the price components that should be selected for the price calculation. + */ + selected_price_component_ids?: string[]; + /** + * The map of coupon ids applicable to the price components + */ + price_component_coupon_ids?: { + [name: string]: string[]; + }; + _price?: /** + * The composite price entity + * example: + * { + * "_id": "c2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_title": "My Composite Price", + * "description": "My Composite Price", + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "is_composite_price": true, + * "price_components": { + * "$relation": [ + * { + * "entity_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_product_id": "target-price-product-id", + * "quantity": 1, + * "item": { + * "_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "_schema": "price", + * "_title": "Test 1", + * "description": "Test 1", + * "tax": { + * "$relation": [ + * { + * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" + * } + * ] + * }, + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "is_composite_price": false + * } + * }, + * { + * "entity_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "_schema": "price", + * "_product_id": "target-price-product-id", + * "quantity": 2, + * "item": { + * "_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", + * "unit_amount": 10000, + * "unit_amount_currency": "EUR", + * "unit_amount_decimal": "100.00", + * "sales_tax": "standard", + * "is_tax_inclusive": false, + * "price_display_in_journeys": "show_price", + * "type": "one_time", + * "_schema": "price", + * "_title": "Test 1", + * "description": "Test 1", + * "tax": { + * "$relation": [ + * { + * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" + * } + * ] + * }, + * "_org": "739224", + * "_created_at": "2022-02-18T10:10:26.439Z", + * "_updated_at": "2022-02-18T11:53:04.191Z", + * "active": true, + * "billing_period": "weekly", + * "billing_duration_unit": "months", + * "notice_time_unit": "months", + * "termination_time_unit": "months", + * "renewal_duration_unit": "months", + * "is_composite_price": false + * } + * } + * ] + * } + * } + */ + CompositePrice; + } + /** + * Echo of the request parameters used to compute the price, in the caller-facing shape. */ - HydratedCompositePrice; + export interface ComputePriceInputs { + [name: string]: any; + type?: ProductCategory; + consumptionHT?: number; + consumptionNT?: number; + consumptionType?: ConsumptionTypeGetAg; + zipCode?: string; + city?: string; + providerId?: string; + billingPeriod?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + referenceDate?: string; // date + } /** - * Represents a composite price input to the pricing library. - * example: - * { - * "amount_subtotal": 10000, - * "amount_total": 10600, - * "currency": "EUR", - * "description": "Annual internet service", - * "price_id": "7e24ff5d-d580-4136-a32f-19191eed039a", - * "product_id": "6241487f-b7fd-428b-ab92-24ee0b37fd84", - * "taxes": [ - * { - * "amount": 600, - * "tax": { - * "active": true, - * "description": "Without Behaviour", - * "rate": 6, - * "region": "DE", - * "type": "VAT", - * "_created_at": "2022-02-07T14:49:08.831Z", - * "_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4", - * "_org": "739224", - * "_schema": "tax", - * "_title": "Tax Without Behaviour", - * "_updated_at": "2022-02-07T14:49:08.831Z" - * } - * } - * ], - * "unit_amount": 10000, - * "unit_amount_net": 10000, - * "pricing_model": "per_unit", - * "_price": { - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "_schema": "price", - * "_title": "Solar Panel Module", - * "description": "Solar Panel Module", - * "active": true, - * "tax": { - * "$relation": [ - * { - * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" - * } - * ] - * }, - * "_id": "7e24ff5d-d580-4136-a32f-19191eed039a", - * "_org": "728", - * "_created_at": "2022-06-03T16:04:10.369Z", - * "_updated_at": "2022-06-03T16:04:10.369Z", - * "pricing_model": "per_unit" - * }, - * "_product": { - * "name": "Cool box", - * "type": "product", - * "_id": "73f857a4-0fbc-4aa6-983f-87c0d6d410a6", - * "_title": "Cool box" - * } - * } + * The compute price payload */ - export interface CompositePriceItem { + export type ComputePriceParams = /* The compute price payload */ /* The compute price payload for power */ ComputePriceParamsPower | /* The compute price payload for gas */ ComputePriceParamsGas; + export interface ComputePriceParamsBase { /** - * Total of all items before (discounts or) taxes are applied. + * The postal code to search for providers */ - amount_subtotal?: number; + postal_code: string; /** - * Total of all items before (discounts or) taxes are applied, as a string with all the decimal places. + * The consumption type */ - amount_subtotal_decimal?: string; + consumption_type?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter"; + /** + * (DEPRECATED - use consumption_HT) The yearly consumption to compute the price in kWh + */ + consumption?: number; + /** + * The yearly HT consumption to compute the price in kWh + */ + consumption_HT?: number; + /** + * The yearly NT consumption to compute the price in kWh + */ + consumption_NT?: number; + /** + * The association id + */ + association_id?: string; + /** + * The billing period (defaults to monthly) + */ + billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + /** + * The optional reference date for the price computation (ISO 8601 format) + */ + reference_date?: string; // date + /** + * The city the postal code belongs to. Not used for price computation, + * only echoed back in `inputs` for display purposes. + * + */ + city?: string; + } + /** + * The compute price payload for gas + */ + export interface ComputePriceParamsGas { + /** + * The postal code to search for providers + */ + postal_code: string; + /** + * The consumption type + */ + consumption_type?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter"; + /** + * (DEPRECATED - use consumption_HT) The yearly consumption to compute the price in kWh + */ + consumption?: number; + /** + * The yearly HT consumption to compute the price in kWh + */ + consumption_HT?: number; + /** + * The yearly NT consumption to compute the price in kWh + */ + consumption_NT?: number; + /** + * The association id + */ + association_id?: string; + /** + * The billing period (defaults to monthly) + */ + billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + /** + * The optional reference date for the price computation (ISO 8601 format) + */ + reference_date?: string; // date + /** + * The city the postal code belongs to. Not used for price computation, + * only echoed back in `inputs` for display purposes. + * + */ + city?: string; + /** + * The type of energy to compute the price + */ + type: "gas"; + concession_type?: /* The concession type for gas */ GasConcessionType; + } + /** + * The compute price payload for power + */ + export interface ComputePriceParamsPower { + /** + * The postal code to search for providers + */ + postal_code: string; + /** + * The consumption type + */ + consumption_type?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter"; + /** + * (DEPRECATED - use consumption_HT) The yearly consumption to compute the price in kWh + */ + consumption?: number; + /** + * The yearly HT consumption to compute the price in kWh + */ + consumption_HT?: number; + /** + * The yearly NT consumption to compute the price in kWh + */ + consumption_NT?: number; + /** + * The association id + */ + association_id?: string; + /** + * The billing period (defaults to monthly) + */ + billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + /** + * The optional reference date for the price computation (ISO 8601 format) + */ + reference_date?: string; // date + /** + * The city the postal code belongs to. Not used for price computation, + * only echoed back in `inputs` for display purposes. + * + */ + city?: string; + /** + * The type of energy to compute the price + */ + type: "power"; + meter_type?: /* The meter type for power */ PowerMeterType; + } + export interface ComputePriceResult { + /** + * The computed total price + */ + amount_total: number; + /** + * The computed total price as decimal + */ + amount_total_decimal: string; + /** + * The computed static price + */ + amount_static?: number; /** - * Total of all items after (discounts and) taxes are applied. + * The computed static price as decimal */ - amount_total?: number; + amount_static_decimal?: any; /** - * Total of all items after (discounts and) taxes are applied, as a string with all the decimal places. + * The computed variable price, for the day period */ - amount_total_decimal?: string; + amount_variable_ht?: number; /** - * The cashback amount. + * The computed variable price, for the day period, as decimal */ - cashback_amount?: number; + amount_variable_decimal_ht?: string; /** - * The cashback amount as a string with all the decimal places. + * The computed unit price, for the day period */ - cashback_amount_decimal?: string; - cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; + unit_amount_variable_ht?: number; /** - * Total amount after cashback is applied. + * The computed unit price, for the day period, as decimal */ - after_cashback_amount_total?: number; + unit_amount_variable_decimal_ht?: string; /** - * Total amount after cashback is applied as a string with all the decimal places. + * The computed variable price, for the night period */ - after_cashback_amount_total_decimal?: string; + amount_variable_nt?: number; /** - * The discount amount. + * The computed variable price, for the night period, as decimal */ - discount_amount?: number; + amount_variable_decimal_nt?: string; /** - * The discount amount as a string with all the decimal places. + * The computed unit price, for the night period */ - discount_amount_decimal?: string; + unit_amount_variable_nt?: number; /** - * The discount percentage, if the applied coupon had a percentage type. + * The computed unit price, for the night period, as decimal */ - discount_percentage?: number; + unit_amount_variable_decimal_nt?: string; /** - * Total amount before discount is applied. + * The currency of the computed price (three-letter ISO currency code) */ - before_discount_amount_total?: number; + currency: /* The currency of the computed price (three-letter ISO currency code) */ /** + * Three-letter ISO currency code, in lowercase. Must be a supported currency. + * ISO 4217 CURRENCY CODES as specified in the documentation: https://www.iso.org/iso-4217-currency-codes.html + * + * example: + * EUR + */ + Currency; /** - * Total amount before discount is applied as a string with all the decimal places. + * The billing period */ - before_discount_amount_total_decimal?: string; + billing_period: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + breakdown: /* Price breakdown */ ComputedPriceBreakdown; /** - * Total amount before discount is applied, excluding taxes. + * A snapshot of the parameters this price was computed from, for display purposes + * (e.g. showing "computed for 3,500 kWh/year"). Included in the `_meta` signature. + * */ - before_discount_amount_subtotal?: number; + inputs?: { + [name: string]: any; + type?: ProductCategory; + consumptionHT?: number; + consumptionNT?: number; + consumptionType?: ConsumptionTypeGetAg; + zipCode?: string; + city?: string; + providerId?: string; + billingPeriod?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + referenceDate?: string; // date + }; + _meta?: /* Signature meta data payload */ SignatureMeta; + } + /** + * The computed price + */ + export interface ComputedBasePrice { /** - * Total amount before discount is applied, excluding taxes, as a string with all the decimal places. + * The computed price */ - before_discount_amount_subtotal_decimal?: string; - metadata?: /* A set of key-value pairs used to store meta data information about an entity. */ MetaData; + amount: number; /** - * The quantity of products being purchased. + * The computed price as decimal */ - quantity?: number; + amount_decimal: string; /** - * The id of the product. + * The computed unit price */ - product_id?: string; + unit_amount?: number; /** - * The id of the price. + * The computed unit price as decimal */ - price_id?: string; + unit_amount_decimal?: string; + } + /** + * Price breakdown + */ + export interface ComputedPriceBreakdown { + static?: /* The computed price components */ ComputedPriceComponents; + variable?: /* The computed price components */ ComputedPriceComponents; + variable_ht?: /* The computed price components */ ComputedPriceComponents; + variable_nt?: /* The computed price components */ ComputedPriceComponents; + } + /** + * The computed price components + */ + export interface ComputedPriceComponents { + [name: string]: /* The computed price */ ComputedBasePrice; + } + /** + * One condition dimension, in the shape a schema's `conditions` array holds it — copy it in verbatim. + */ + export interface ConditionDefinition { /** - * An arbitrary string attached to the price item. Often useful for displaying to users. Defaults to product name. + * Stable identity of the condition, supplied on creation and round-tripped unchanged. A + * catalog condition keeps the id the catalog gives it. + * + * example: + * d5839b94-ba20-4225-a78e-76951d352bd6 */ - description?: string; + id: string; // uuid /** - * The description for the product. + * How variants and resolve contexts refer to this condition, independent of attribute + * names. `default` and names beginning with `_` are reserved and are ignored here. + * + * example: + * postal_code */ - product_description?: string; + name: string; /** - * The name for the product. + * Human-readable name of the condition. + * example: + * Postal Code */ - product_name?: string; - price_mappings?: /** + label: string; + type: /** + * The kind of value a condition holds, which decides how a pinned value is matched against a + * resolve context. + * + * - `string`: an arbitrary string, matched exactly and case-sensitively + * - `number`: a numeric value + * - `date`: a single date + * - `daterange`: a window with a from and an until timestamp; either end may be left open + * - `boolean`: a true/false value + * - `select`: one of the values declared in `options`, which is always a closed vocabulary + * - `location`: a geographic value, shaped by `format` + * + */ + ConditionType; + /** + * The vocabulary of a `select` condition, absent for every other type. Each entry is the + * value itself or an object carrying that value and a display `title`, which is never + * matched. + * + * Always closed: a pinned value outside it is `CONDITION_VALUE_INVALID`, and while + * `options` is absent or empty the condition admits no pin at all. Not enforced on + * resolve, where a context value outside the vocabulary matches nothing. + * * example: * [ + * "private", * { - * "price_id": "589B011B-F8D9-4F8E-AD71-BACE4B543C0F", - * "frequency_unit": "weekly", - * "value": 1000.245, - * "name": "avg consumption", - * "metadata": { - * "journey_title": "energy journey", - * "step_name": "avg consumption picker" - * } + * "value": "commercial", + * "title": "Commercial customers" * } * ] */ - PriceInputMappings; + options?: (string | { + value: string; + title?: string; + })[]; /** - * Specifies whether the price is considered `inclusive` of taxes or not. + * The value shape of a `location` condition. Absent for every other type. */ - is_tax_inclusive?: boolean; + format?: "zipcode" | "zipcode_town"; + } + /** + * A named bundle of condition definitions, built in for one entity type. + */ + export interface ConditionSet { /** - * The snapshot of the product. + * Identifies the set within this entity type's catalog. * example: - * { - * "type": "product", - * "_schema": "product", - * "_title": "Solar Panel with Battery Storage", - * "name": "Solar Panel with Battery Storage", - * "code": "SOLAR-BATT", - * "active": true, - * "description": "Solar Panel with battery solution, optimized for max efficiency. ", - * "feature": [ - * { - * "_tags": [], - * "feature": "Eco-Panels" - * }, - * { - * "_tags": [], - * "feature": "Remote Management Platform" - * }, - * { - * "_tags": [], - * "feature": "Battery Remote Control" - * }, - * { - * "_tags": [], - * "feature": "Mobile App" - * } - * ], - * "cross_sellable_products": { - * "$relation": [ - * { - * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", - * "_schema": "product", - * "_tags": [] - * }, - * { - * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", - * "_tags": [] - * } - * ] - * }, - * "product_images": { - * "$relation": [ - * { - * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" - * }, - * { - * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" - * } - * ] - * }, - * "product_downloads": { - * "$relation": [ - * { - * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" - * } - * ] - * }, - * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", - * "_org": "728", - * "_created_at": "2022-06-03T15: 52: 27.512Z", - * "_updated_at": "2022-06-03T16: 05: 15.029Z", - * "price_options": { - * "$relation": [ - * { - * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", - * "_tags": [] - * }, - * { - * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", - * "_tags": [] - * } - * ] - * } - * } + * delivery_area + */ + id: string; + /** + * Human-readable name of the set. + * example: + * Delivery Area + */ + label: string; + /** + * What the set is for, and when to reach for it. + */ + description: string; + /** + * The condition definitions to copy into the schema's own `conditions` array. + */ + conditions: /* One condition dimension, in the shape a schema's `conditions` array holds it — copy it in verbatim. */ ConditionDefinition[]; + } + export interface ConditionSetCatalog { + /** + * The condition sets built in for the requested entity type, in the order they are offered. */ - _product?: { - [name: string]: any; - /** - * The description for the product - */ - description?: string; - /** - * The product code - */ - code?: string; - /** - * The type of Product: - * - * | type | description | - * |----| ----| - * | `product` | Represents a physical good | - * | `service` | Represents a service or virtual product | - * - */ - type?: "product" | "service"; - /** - * The product main name - */ - name?: string; + results: /* A named bundle of condition definitions, built in for one entity type. */ ConditionSet[]; + } + /** + * The kind of value a condition holds, which decides how a pinned value is matched against a + * resolve context. + * + * - `string`: an arbitrary string, matched exactly and case-sensitively + * - `number`: a numeric value + * - `date`: a single date + * - `daterange`: a window with a from and an until timestamp; either end may be left open + * - `boolean`: a true/false value + * - `select`: one of the values declared in `options`, which is always a closed vocabulary + * - `location`: a geographic value, shaped by `format` + * + */ + export type ConditionType = "string" | "number" | "date" | "daterange" | "boolean" | "select" | "location"; + /** + * Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. + */ + export type ConditionalEntitySlug = "product" | "price" | "coupon"; + /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + export type ConditionalPricingError = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + { + code: "SCHEMA_NOT_FOUND"; + details: { /** - * The product categories + * The entity type the request addressed. + * example: + * price */ - categories?: string[]; - feature?: { - /** - * An arbitrary set of tags attached to a feature - */ - _tags?: string[]; - feature?: string; - }[]; + schema: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_NOT_FOUND"; + details: { /** - * Stores references to products that can be cross sold with the current product. + * The entity type the request addressed. + * example: + * price */ - cross_sellable_products?: { - $relation?: EntityRelation[]; - }; + schema: string; /** - * Stores references to a set of file images of the product + * The conditional entity the request addressed. + * example: + * price-sp26d1yo */ - product_images?: /* Stores references to a set of file images of the product */ { - $relation?: EntityRelation[]; - } | File[]; + entity_id: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_TYPE_MISMATCH"; + details: { /** - * Stores references to a set of files downloadable from the product. - * e.g: tech specifications, quality control sheets, privacy policy agreements - * - */ - product_downloads?: /** - * Stores references to a set of files downloadable from the product. - * e.g: tech specifications, quality control sheets, privacy policy agreements - * + * The entity type the request addressed. + * example: + * price */ - { - $relation?: EntityRelation[]; - } | File[]; + schema: string; /** - * A set of [prices](/api/pricing#tag/simple_price_schema) or [composite prices](/api/pricing#tag/dynamic_price_schema) for the current product. + * The conditional entity the request addressed. + * example: + * price-sp26d1yo */ - price_options?: { - $relation?: EntityRelation[]; - }; + entity_id: string; /** - * Stores references to the availability files that define where this product is available. - * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. + * The entity type that id belongs to. Where it is a conditional entity type, + * it is the slug to send instead. * + * example: + * product */ - _availability_files?: File[]; - /** - * The product id - */ - _id?: string; - /** - * The autogenerated product title - */ - _title?: string; - /** - * The organization id the product belongs to - */ - _org_id?: string; + actual_schema: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "ENTITY_NOT_CONDITIONAL"; + details: { /** - * The product creation date + * The entity type the request addressed. + * example: + * price */ - _created_at?: string; + schema: string; /** - * The product last update date + * The conditional entity the request addressed. + * example: + * price-sp26d1yo */ - _updated_at?: string; + entity_id: string; }; /** - * price item id + * Error message */ - _id?: string; + message: string; /** - * The unit amount value + * The HTTP status code */ - unit_amount?: number; + status?: number; /** - * The unit amount in eur to be charged, represented as a decimal string with at most 12 decimal places. + * The cause of the error (visible for bad requests - http 400) */ - unit_amount_decimal?: string; + cause?: string; /** - * The unit amount before any discount is applied + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - before_discount_unit_amount?: number; + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_NOT_FOUND"; + details: { + /** + * The conditional entity the request addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + }; /** - * The unit amount before any discount is applied, represented as a decimal string with at most 12 decimal places. + * Error message */ - before_discount_unit_amount_decimal?: string; + message: string; /** - * The unit gross amount before any discount is applied + * The HTTP status code */ - before_discount_unit_amount_gross?: number; + status?: number; /** - * The unit gross amount before any discount is applied, represented as a decimal string with at most 12 decimal places. + * The cause of the error (visible for bad requests - http 400) */ - before_discount_unit_amount_gross_decimal?: string; + cause?: string; /** - * The unit net amount before any discount is applied + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - before_discount_unit_amount_net?: number; + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VERSION_NOT_FOUND"; + details: { + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the request addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; /** - * The unit net amount before any discount is applied, represented as a decimal string with at most 12 decimal places. + * Error message */ - before_discount_unit_amount_net_decimal?: string; + message: string; /** - * The discount amount applied for each unit + * The HTTP status code */ - unit_discount_amount?: number; + status?: number; /** - * The discount amount applied for each unit represented as a decimal string + * The cause of the error (visible for bad requests - http 400) */ - unit_discount_amount_decimal?: string; + cause?: string; /** - * The unit gross amount value. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - unit_amount_gross?: number; + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "NO_MATCHES"; + details: { + /** + * The entity type the request addressed. + * example: + * price + */ + schema: string; + /** + * The conditional entity the resolve was scoped to. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; /** - * The unit gross amount value. + * Error message */ - unit_amount_gross_decimal?: string; + message: string; /** - * Net unit amount without taxes or discounts. + * The HTTP status code */ - unit_amount_net?: number; + status?: number; /** - * Net unit amount without taxes or discounts. + * The cause of the error (visible for bad requests - http 400) */ - unit_amount_net_decimal?: string; + cause?: string; /** - * The net discount amount applied for each unit + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - unit_discount_amount_net?: number; - /** - * The net discount amount applied for each unit represented as a decimal string + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - unit_discount_amount_net_decimal?: string; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "NO_ACTIVE_VERSION"; + details: { + /** + * The variant the request addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The instant a version in effect was asked for at. + * example: + * 2026-06-01T00:00:00.000Z + */ + as_of: string; + }; /** - * The discount amount applied to the tax + * Error message */ - tax_discount_amount?: number; + message: string; /** - * The discount amount applied to the tax represented as a decimal string + * The HTTP status code */ - tax_discount_amount_decimal?: string; + status?: number; /** - * The net discount amount applied + * The cause of the error (visible for bad requests - http 400) */ - discount_amount_net?: number; + cause?: string; /** - * The net discount amount applied represented as a decimal string + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - discount_amount_net_decimal?: string; - /** - * Total tax amount for this line item. + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - amount_tax?: number; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "AMBIGUOUS_RESOLUTION"; + details: { + /** + * Every variant that applied, each with the conditions it pins. + */ + candidates: [ + { + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }, + { + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }, + ...{ + /** + * The candidate variant. + * example: + * var-46045 + */ + variant_id: string; + conditions: /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + VariantConditions; + }[] + ]; + }; /** - * The tax amount before any discount is applied + * Error message */ - before_discount_tax_amount?: number; + message: string; /** - * The tax amount before any discount is applied represented as a decimal string - */ - before_discount_tax_amount_decimal?: string; - currency?: /** - * Three-letter ISO currency code, in lowercase. Must be a supported currency. - * ISO 4217 CURRENCY CODES as specified in the documentation: https://www.iso.org/iso-4217-currency-codes.html - * - * example: - * EUR + * The HTTP status code */ - Currency; + status?: number; /** - * The taxes applied to the price item. + * The cause of the error (visible for bad requests - http 400) */ - taxes?: (/* A tax amount associated with a specific tax rate. */ TaxAmount)[]; + cause?: string; /** - * The sum of amounts of the price items by recurrence. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - recurrences?: (/* An amount associated with a specific recurrence. */ RecurrenceAmount)[]; - /** - * The coupons applicable to the composite price item + related (cashback) amounts + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - _coupons?: ({ + string | { [name: string]: any; - _id: EntityId /* uuid */; - /** - * The auto-generated title for the title - */ - _title: string; - /** - * Organization Id the entity belongs to - */ - _org: string; - /** - * The schema of the entity, for coupons it is always `coupon` - */ - _schema: "coupon"; - _tags?: string[]; - /** - * The creation date for the opportunity - */ - _created_at: string; // date-time - /** - * The date the coupon was last updated - */ - _updated_at: string; // date-time - name: string | null; - description?: string | null; - type: "fixed" | "percentage"; - category: "discount" | "cashback"; - /** - * Use if type is set to percentage. The percentage to be discounted, represented as a whole integer. - */ - percentage_value?: string | null; - /** - * Use if type is set to fixed. The fixed amount in cents to be discounted, represented as a whole integer. - */ - fixed_value?: number; - /** - * Use if type is set to fixed. The unit amount in eur to be discounted, represented as a decimal string with at most 12 decimal places. - */ - fixed_value_decimal?: string; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "TUPLE_CONFLICT"; + details: { /** - * Use if type is set to fixed. Three-letter ISO currency code, in lowercase. - */ - fixed_value_currency?: /* Use if type is set to fixed. Three-letter ISO currency code, in lowercase. */ /** - * Three-letter ISO currency code, in lowercase. Must be a supported currency. - * ISO 4217 CURRENCY CODES as specified in the documentation: https://www.iso.org/iso-4217-currency-codes.html - * + * The variant the write addressed. * example: - * EUR - */ - Currency; - cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; - active?: boolean; - /** - * Whether the coupon requires a promo code to be applied - */ - requires_promo_code?: boolean; - /** - * The cashback amount. - */ - cashback_amount?: number; - /** - * The cashback amount as a string with all the decimal places. - */ - cashback_amount_decimal?: string; - /** - * Total amount after cashback is applied. + * var-46045 */ - after_cashback_amount_total?: number; + variant_id: string; /** - * Total amount after cashback is applied as a string with all the decimal places. + * The variant already holding the tuple, where the write read it back. + * example: + * var-50667 */ - after_cashback_amount_total_decimal?: string; - } & /* The shared properties for the coupon entity and coupon item entity */ (/* The shared properties for the coupon entity and coupon item entity */ CouponItem))[]; + conflicting_variant_id?: string; + }; /** - * When set to true on a `_price` displayed as OnRequest (`show_as_on_request: 'on_request'`) this flag means the price has been approved and can now be displayed to the customer. This flag is only valid for prices shown as 'on_request'. + * Error message */ - on_request_approved?: boolean; + message: string; /** - * The flag for prices that contain price components. + * The HTTP status code */ - is_composite_price: true; + status?: number; /** - * Contains price item configurations, per price component, when the main price item is a [composite price](/api/pricing#tag/dynamic_price_schema). + * The cause of the error (visible for bad requests - http 400) */ - item_components?: /** - * Represents a price item - * example: - * { - * "amount_subtotal": 10000, - * "amount_total": 10600, - * "currency": "EUR", - * "description": "Annual internet service", - * "price_id": "7e24ff5d-d580-4136-a32f-19191eed039a", - * "product_id": "6241487f-b7fd-428b-ab92-24ee0b37fd84", - * "taxes": [ - * { - * "amount": 600, - * "tax": { - * "active": true, - * "description": "Without Behaviour", - * "rate": 6, - * "region": "DE", - * "type": "VAT", - * "_created_at": "2022-02-07T14:49:08.831Z", - * "_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4", - * "_org": "739224", - * "_schema": "tax", - * "_title": "Tax Without Behaviour", - * "_updated_at": "2022-02-07T14:49:08.831Z" - * } - * }, - * { - * "amount": 600, - * "tax": { - * "active": true, - * "description": "Without Behaviour", - * "rate": 6, - * "region": "DE", - * "type": "VAT", - * "_created_at": "2022-02-07T14:49:08.831Z", - * "_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4", - * "_org": "739224", - * "_schema": "tax", - * "_title": "Tax Without Behaviour", - * "_updated_at": "2022-02-07T14:49:08.831Z" - * } - * } - * ], - * "unit_amount": 10000, - * "unit_amount_net": 10000, - * "pricing_model": "per_unit", - * "_price": { - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "_schema": "price", - * "_title": "Solar Panel Module", - * "description": "Solar Panel Module", - * "active": true, - * "tax": { - * "$relation": [ - * { - * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" - * }, - * { - * "entity_id": "24641e82-0690-4135-8b43-ef12a9b1c5dc" - * } - * ] - * }, - * "_id": "7e24ff5d-d580-4136-a32f-19191eed039a", - * "_org": "728", - * "_created_at": "2022-06-03T16:04:10.369Z", - * "_updated_at": "2022-06-03T16:04:10.369Z", - * "pricing_model": "per_unit" - * }, - * "_product": { - * "name": "Cool box", - * "type": "product", - * "_id": "73f857a4-0fbc-4aa6-983f-87c0d6d410a6", - * "_title": "Cool box" - * } - * } + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - PriceItem[]; - total_details?: /* The total details with tax (and discount) aggregated totals. */ TotalDetails; + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VERSION_CONFLICT"; + details: { + /** + * The variant the write addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The instant already claimed by a version of that variant. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; /** - * The price snapshot data. + * Error message */ - _price?: /* The price snapshot data. */ /** - * The composite price entity - * example: - * { - * "_id": "c2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_title": "My Composite Price", - * "description": "My Composite Price", - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "is_composite_price": true, - * "price_components": { - * "$relation": [ - * { - * "entity_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_product_id": "target-price-product-id", - * "quantity": 1, - * "item": { - * "_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "_schema": "price", - * "_title": "Test 1", - * "description": "Test 1", - * "tax": { - * "$relation": [ - * { - * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" - * } - * ] - * }, - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "is_composite_price": false - * } - * }, - * { - * "entity_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_product_id": "target-price-product-id", - * "quantity": 2, - * "item": { - * "_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "_schema": "price", - * "_title": "Test 1", - * "description": "Test 1", - * "tax": { - * "$relation": [ - * { - * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" - * } - * ] - * }, - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "is_composite_price": false - * } - * } - * ] - * } - * } + message: string; + /** + * The HTTP status code */ - CompositePrice; - } - /** - * Represents a composite price input to the pricing library. - */ - export interface CompositePriceItemDto { - metadata?: /* A set of key-value pairs used to store meta data information about an entity. */ MetaData; + status?: number; /** - * The quantity of products being purchased. + * The cause of the error (visible for bad requests - http 400) */ - quantity?: number; + cause?: string; /** - * The id of the product. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - product_id?: string; + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNDEFINED"; + details: { + /** + * The condition the request named and the schema does not define. + * example: + * postal_code + */ + condition_name: string; + }; /** - * The id of the price. + * Error message */ - price_id?: string; + message: string; /** - * An arbitrary string attached to the price item. Often useful for displaying to users. Defaults to product name. + * The HTTP status code */ - description?: string; + status?: number; /** - * The description for the product. + * The cause of the error (visible for bad requests - http 400) */ - product_description?: string; + cause?: string; /** - * The name for the product. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - product_name?: string; - price_mappings?: /** - * example: - * [ - * { - * "price_id": "589B011B-F8D9-4F8E-AD71-BACE4B543C0F", - * "frequency_unit": "weekly", - * "value": 1000.245, - * "name": "avg consumption", - * "metadata": { - * "journey_title": "energy journey", - * "step_name": "avg consumption picker" - * } - * } - * ] + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - PriceInputMappings; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_PIN_UNDECLARED"; + details: { + /** + * The condition the variant pins and the schema no longer declares. + * example: + * postal_code + */ + condition_name: string; + /** + * One variant carrying such a pin. + * example: + * var-46045 + */ + variant_id: string; + }; /** - * Specifies whether the price is considered `inclusive` of taxes or not. + * Error message */ - is_tax_inclusive?: boolean; + message: string; /** - * The snapshot of the product. - * example: - * { - * "type": "product", - * "_schema": "product", - * "_title": "Solar Panel with Battery Storage", - * "name": "Solar Panel with Battery Storage", - * "code": "SOLAR-BATT", - * "active": true, - * "description": "Solar Panel with battery solution, optimized for max efficiency. ", - * "feature": [ - * { - * "_tags": [], - * "feature": "Eco-Panels" - * }, - * { - * "_tags": [], - * "feature": "Remote Management Platform" - * }, - * { - * "_tags": [], - * "feature": "Battery Remote Control" - * }, - * { - * "_tags": [], - * "feature": "Mobile App" - * } - * ], - * "cross_sellable_products": { - * "$relation": [ - * { - * "entity_id": "068d0713-a650-4668-9ed2-eca7be31e337", - * "_schema": "product", - * "_tags": [] - * }, - * { - * "entity_id": "c8402ee7-fba9-4f3d-bffd-6803ca655782", - * "_tags": [] - * } - * ] - * }, - * "product_images": { - * "$relation": [ - * { - * "entity_id": "37bdeaaa-65fe-403e-9894-65b01cd277f1" - * }, - * { - * "entity_id": "56dde657-795c-41bb-bf53-98fd586b7e6e" - * } - * ] - * }, - * "product_downloads": { - * "$relation": [ - * { - * "entity_id": "64211361-8759-414b-81c0-afbf24f83aa9" - * } - * ] - * }, - * "_id": "a7f4771a-6368-4d77-bb01-71f1e4902de5", - * "_org": "728", - * "_created_at": "2022-06-03T15: 52: 27.512Z", - * "_updated_at": "2022-06-03T16: 05: 15.029Z", - * "price_options": { - * "$relation": [ - * { - * "entity_id": "9c36c23b-1574-4193-beff-b1b5e1124bc7", - * "_tags": [] - * }, - * { - * "entity_id": "146aa2cc-f267-4d5e-bda4-cbe2669b7741", - * "_tags": [] - * } - * ] - * } - * } + * The HTTP status code */ - _product?: { + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "OPERATOR_UNSUPPORTED"; + details: { /** - * The description for the product + * example: + * postal_code */ - description?: string; + condition_name: string; /** - * The product code + * The type the schema declares that condition with. + * example: + * location */ - code?: string; + condition_type: string; /** - * The type of Product: - * - * | type | description | - * |----| ----| - * | `product` | Represents a physical good | - * | `service` | Represents a service or virtual product | + * The predicate the context or filter asked for, or `sort` where a listing + * asked to order by a condition whose type has no order. * + * example: + * between */ - type?: "product" | "service"; + operator: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONTEXT_FORMAT_INVALID"; + details: { /** - * The product main name + * example: + * postal_code */ - name?: string; + condition_name: string; /** - * The product categories + * What a value for that condition has to be, in prose. + * example: + * a postal code */ - categories?: string[]; - feature?: { - /** - * An arbitrary set of tags attached to a feature - */ - _tags?: string[]; - feature?: string; - }[]; + expected: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_VALUE_INVALID"; + details: { /** - * Stores references to products that can be cross sold with the current product. + * example: + * segment */ - cross_sellable_products?: { - $relation?: EntityRelation[]; - }; + condition_name: string; /** - * Stores references to a set of file images of the product + * The value the write pinned, as it arrived. + * example: + * industrial */ - product_images?: /* Stores references to a set of file images of the product */ { - $relation?: EntityRelation[]; - } | File[]; + value: any; /** - * Stores references to a set of files downloadable from the product. - * e.g: tech specifications, quality control sheets, privacy policy agreements + * The vocabulary as enforced, after any entries this deploy cannot read have + * been dropped. * + * example: + * [ + * "private", + * "commercial" + * ] */ - product_downloads?: /** - * Stores references to a set of files downloadable from the product. - * e.g: tech specifications, quality control sheets, privacy policy agreements - * + options: [ + string, + ...string[] + ]; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNCONFIGURED"; + details: { + /** + * The condition whose vocabulary is not configured yet. + * example: + * segment */ - { - $relation?: EntityRelation[]; - } | File[]; + condition_name: string; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "TOO_MANY_MATCHES"; + details: { /** - * A set of [prices](/api/pricing#tag/simple_price_schema) or [composite prices](/api/pricing#tag/dynamic_price_schema) for the current product. + * The most variants one resolve may compose. + * example: + * 100 */ - price_options?: { - $relation?: EntityRelation[]; - }; + limit: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "WRITE_CONFLICT"; + details: { /** - * Stores references to the availability files that define where this product is available. - * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. - * + * The variant the write addressed. + * example: + * var-46045 */ - _availability_files?: File[]; + variant_id: string; /** - * The product id + * The version the write addressed, where one was addressed. + * example: + * 2027-01-01T00:00:00.000Z */ - _id?: string; + valid_from?: string; /** - * The autogenerated product title + * The revision the write required the stored version to still be at. + * example: + * 3 */ - _title?: string; + expected_revision?: number; /** - * The organization id the product belongs to + * The revision the version is actually at, where the failed write read it back. + * example: + * 4 */ - _org_id?: string; + current_revision?: number; + }; + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; + /** + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "OFFSET_WINDOW_EXCEEDED"; + details: { /** - * The product creation date + * The offset the request asked for. + * example: + * 24990 */ - _created_at?: string; + from: number; /** - * The product last update date + * The page size the request asked for, after clamping. + * example: + * 25 */ - _updated_at?: string; + size: number; + /** + * The last row this deploy's index will serve from an offset. + * example: + * 25000 + */ + window: number; }; - external_fees_mappings?: /** - * example: - * [ - * { - * "price_id": "589B011B-F8D9-4F8E-AD71-BACE4B543C0F", - * "frequency_unit": "weekly", - * "amount_total": 1000, - * "amount_total_decimal": "10.00" - * } - * ] - */ - ExternalFeeMappings; - external_fees_metadata?: ExternalFeeMetadata; - external_location_metadata?: /* The provider entity */ ExternalLocationMetadata; - external_price_metadata?: ExternalPriceMetadata; - _immutable_pricing_details?: /* The result from the calculation of a set of price items. */ PricingDetails; /** - * The ids of the coupons applicable to the price item + * Error message */ - coupon_ids?: string[]; + message: string; /** - * The taxes applied to the price item. + * The HTTP status code */ - taxes?: (/* A valid tax rate from a client. */ TaxAmountDto)[]; + status?: number; /** - * The taxes applied to the price item. + * The cause of the error (visible for bad requests - http 400) */ - recurrences?: (/* An amount associated with a specific recurrence. */ RecurrenceAmountDto)[]; + cause?: string; /** - * The coupons applicable to the price item + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - _coupons?: (/* The shared properties for the coupon entity and coupon item entity */ CouponItem)[]; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CURSOR_INVALID"; + details: { + /** + * Which check the cursor failed, in prose. + * example: + * The cursor was issued for a different sort order + */ + reason: string; + }; /** - * The flag for prices that contain price components. + * Error message */ - is_composite_price: true; + message: string; /** - * Contains price item configurations, per price component, when the main price item is a [composite price](/api/pricing#tag/dynamic_price_schema). + * The HTTP status code */ - item_components?: /* Represents a price input to the pricing library. */ PriceItemDto[]; + status?: number; /** - * The ids of the price components that should be selected for the price calculation. + * The cause of the error (visible for bad requests - http 400) */ - selected_price_component_ids?: string[]; + cause?: string; /** - * The map of coupon ids applicable to the price components + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - price_component_coupon_ids?: { - [name: string]: string[]; - }; - _price?: /** - * The composite price entity - * example: - * { - * "_id": "c2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_title": "My Composite Price", - * "description": "My Composite Price", - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "is_composite_price": true, - * "price_components": { - * "$relation": [ - * { - * "entity_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_product_id": "target-price-product-id", - * "quantity": 1, - * "item": { - * "_id": "comp1-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "_schema": "price", - * "_title": "Test 1", - * "description": "Test 1", - * "tax": { - * "$relation": [ - * { - * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" - * } - * ] - * }, - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "is_composite_price": false - * } - * }, - * { - * "entity_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "_schema": "price", - * "_product_id": "target-price-product-id", - * "quantity": 2, - * "item": { - * "_id": "comp2-2a95ca9-7a50-41a4-a73c-b5fb1a57d40f", - * "unit_amount": 10000, - * "unit_amount_currency": "EUR", - * "unit_amount_decimal": "100.00", - * "sales_tax": "standard", - * "is_tax_inclusive": false, - * "price_display_in_journeys": "show_price", - * "type": "one_time", - * "_schema": "price", - * "_title": "Test 1", - * "description": "Test 1", - * "tax": { - * "$relation": [ - * { - * "entity_id": "18bbbc2e-2c37-4f91-924a-07ae60d830e4" - * } - * ] - * }, - * "_org": "739224", - * "_created_at": "2022-02-18T10:10:26.439Z", - * "_updated_at": "2022-02-18T11:53:04.191Z", - * "active": true, - * "billing_period": "weekly", - * "billing_duration_unit": "months", - * "notice_time_unit": "months", - * "termination_time_unit": "months", - * "renewal_duration_unit": "months", - * "is_composite_price": false - * } - * } - * ] - * } - * } + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - CompositePrice; - } - /** - * Echo of the request parameters used to compute the price, in the caller-facing shape. - */ - export interface ComputePriceInputs { - [name: string]: any; - type?: ProductCategory; - consumptionHT?: number; - consumptionNT?: number; - consumptionType?: ConsumptionTypeGetAg; - zipCode?: string; - city?: string; - providerId?: string; - billingPeriod?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; - referenceDate?: string; // date - } - /** - * The compute price payload - */ - export type ComputePriceParams = /* The compute price payload */ /* The compute price payload for power */ ComputePriceParamsPower | /* The compute price payload for gas */ ComputePriceParamsGas; - export interface ComputePriceParamsBase { + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_LIMIT_REACHED"; + details: { + /** + * Variants this entity already holds. + * example: + * 5000 + */ + variant_count: number; + /** + * Variants this entity may hold. Configurable per deploy. + * example: + * 5000 + */ + cap: number; + }; /** - * The postal code to search for providers + * Error message */ - postal_code: string; + message: string; /** - * The consumption type + * The HTTP status code */ - consumption_type?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter"; + status?: number; /** - * (DEPRECATED - use consumption_HT) The yearly consumption to compute the price in kWh + * The cause of the error (visible for bad requests - http 400) */ - consumption?: number; + cause?: string; /** - * The yearly HT consumption to compute the price in kWh + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - consumption_HT?: number; - /** - * The yearly NT consumption to compute the price in kWh + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - consumption_NT?: number; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "PIN_FORMAT_INVALID"; + details: { + /** + * example: + * valid_period + */ + condition_name: string; + /** + * The type the schema declares that condition with. + * example: + * daterange + */ + condition_type: string; + /** + * What a pin for that condition has to be, in prose. + * example: + * an object carrying a from and an until date, either may be open + */ + expected: string; + /** + * The value the write pinned, as it arrived. + * example: + * 2027-01-01/2027-12-31 + */ + value: any; + }; /** - * The association id + * Error message */ - association_id?: string; + message: string; /** - * The billing period (defaults to monthly) + * The HTTP status code */ - billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + status?: number; /** - * The optional reference date for the price computation (ISO 8601 format) + * The cause of the error (visible for bad requests - http 400) */ - reference_date?: string; // date + cause?: string; /** - * The city the postal code belongs to. Not used for price computation, - * only echoed back in `inputs` for display purposes. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - city?: string; - } - /** - * The compute price payload for gas - */ - export interface ComputePriceParamsGas { - /** - * The postal code to search for providers + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - postal_code: string; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_UNPINNED"; + details: { + /** + * The conditional entity the item addressed. + * example: + * price-sp26d1yo + */ + entity_id: string; + }; /** - * The consumption type + * Error message */ - consumption_type?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter"; + message: string; /** - * (DEPRECATED - use consumption_HT) The yearly consumption to compute the price in kWh + * The HTTP status code */ - consumption?: number; + status?: number; /** - * The yearly HT consumption to compute the price in kWh + * The cause of the error (visible for bad requests - http 400) */ - consumption_HT?: number; + cause?: string; /** - * The yearly NT consumption to compute the price in kWh + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - consumption_NT?: number; + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * + */ + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "LAST_VERSION_UNDELETABLE"; + details: { + /** + * The variant whose last version the delete addressed. + * example: + * var-46045 + */ + variant_id: string; + /** + * The version the delete addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + }; /** - * The association id + * Error message */ - association_id?: string; + message: string; /** - * The billing period (defaults to monthly) + * The HTTP status code */ - billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + status?: number; /** - * The optional reference date for the price computation (ISO 8601 format) + * The cause of the error (visible for bad requests - http 400) */ - reference_date?: string; // date + cause?: string; /** - * The city the postal code belongs to. Not used for price computation, - * only echoed back in `inputs` for display purposes. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - city?: string; - /** - * The type of energy to compute the price + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - type: "gas"; - concession_type?: /* The concession type for gas */ GasConcessionType; - } - /** - * The compute price payload for power - */ - export interface ComputePriceParamsPower { + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "CONDITION_UNREADABLE"; + details: { + /** + * The condition whose definition this deploy cannot read. + * example: + * delivery_area + */ + condition_name: string; + /** + * Which field of the definition cannot be read, named as the schema spells it. + * example: + * format + */ + unreadable: "format" | "options"; + }; /** - * The postal code to search for providers + * Error message */ - postal_code: string; + message: string; /** - * The consumption type + * The HTTP status code */ - consumption_type?: "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter"; + status?: number; /** - * (DEPRECATED - use consumption_HT) The yearly consumption to compute the price in kWh + * The cause of the error (visible for bad requests - http 400) */ - consumption?: number; + cause?: string; /** - * The yearly HT consumption to compute the price in kWh + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - consumption_HT?: number; - /** - * The yearly NT consumption to compute the price in kWh + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - consumption_NT?: number; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "SORT_INVALID"; + details: { + /** + * What a `sort` has to be, in prose. + * example: + * conditions.:asc or conditions.:desc, naming a string, select, number or date condition + */ + expected: string; + }; /** - * The association id + * Error message */ - association_id?: string; + message: string; /** - * The billing period (defaults to monthly) + * The HTTP status code */ - billing_period?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; + status?: number; /** - * The optional reference date for the price computation (ISO 8601 format) + * The cause of the error (visible for bad requests - http 400) */ - reference_date?: string; // date + cause?: string; /** - * The city the postal code belongs to. Not used for price computation, - * only echoed back in `inputs` for display purposes. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - city?: string; - /** - * The type of energy to compute the price + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - type: "power"; - meter_type?: /* The meter type for power */ PowerMeterType; - } - export interface ComputePriceResult { + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "DEFAULT_MARKER_RESERVED"; + details: { + /** + * The marker, spelled as the request spelled it. + * example: + * default + */ + condition_name: string; + }; /** - * The computed total price + * Error message */ - amount_total: number; + message: string; /** - * The computed total price as decimal + * The HTTP status code */ - amount_total_decimal: string; + status?: number; /** - * The computed static price + * The cause of the error (visible for bad requests - http 400) */ - amount_static?: number; + cause?: string; /** - * The computed static price as decimal + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - amount_static_decimal?: any; - /** - * The computed variable price, for the day period + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - amount_variable_ht?: number; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "DEFAULT_VARIANT_PINS_CONDITIONS"; + details: { + /** + * The conditions the write pinned beside the marker. + * example: + * [ + * "postal_code" + * ] + */ + condition_names: string[]; + }; /** - * The computed variable price, for the day period, as decimal + * Error message */ - amount_variable_decimal_ht?: string; + message: string; /** - * The computed unit price, for the day period + * The HTTP status code */ - unit_amount_variable_ht?: number; + status?: number; /** - * The computed unit price, for the day period, as decimal + * The cause of the error (visible for bad requests - http 400) */ - unit_amount_variable_decimal_ht?: string; + cause?: string; /** - * The computed variable price, for the night period + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - amount_variable_nt?: number; - /** - * The computed variable price, for the night period, as decimal + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - amount_variable_decimal_nt?: string; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VALID_FROM_IMMUTABLE"; + details: { + /** + * The version the request addressed, by the instant it takes effect from. + * example: + * 2027-01-01T00:00:00.000Z + */ + addressed: string; + /** + * The instant the body asked for instead, canonicalized. + * example: + * 2027-04-01T00:00:00.000Z + */ + requested: string; + }; /** - * The computed unit price, for the night period + * Error message */ - unit_amount_variable_nt?: number; + message: string; /** - * The computed unit price, for the night period, as decimal + * The HTTP status code */ - unit_amount_variable_decimal_nt?: string; + status?: number; /** - * The currency of the computed price (three-letter ISO currency code) - */ - currency: /* The currency of the computed price (three-letter ISO currency code) */ /** - * Three-letter ISO currency code, in lowercase. Must be a supported currency. - * ISO 4217 CURRENCY CODES as specified in the documentation: https://www.iso.org/iso-4217-currency-codes.html - * - * example: - * EUR + * The cause of the error (visible for bad requests - http 400) */ - Currency; + cause?: string; /** - * The billing period + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - billing_period: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; - breakdown: /* Price breakdown */ ComputedPriceBreakdown; - /** - * A snapshot of the parameters this price was computed from, for display purposes - * (e.g. showing "computed for 3,500 kWh/year"). Included in the `_meta` signature. + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - inputs?: { + string | { [name: string]: any; - type?: ProductCategory; - consumptionHT?: number; - consumptionNT?: number; - consumptionType?: ConsumptionTypeGetAg; - zipCode?: string; - city?: string; - providerId?: string; - billingPeriod?: "weekly" | "monthly" | "every_quarter" | "every_6_months" | "yearly" | "one_time"; - referenceDate?: string; // date + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VARIANT_CONDITIONS_IMMUTABLE"; + details: { + /** + * The variant whose conditions the write would have changed. + * example: + * var-46045 + */ + variant_id: string; }; - _meta?: /* Signature meta data payload */ SignatureMeta; - } - /** - * The computed price - */ - export interface ComputedBasePrice { - /** - * The computed price - */ - amount: number; /** - * The computed price as decimal + * Error message */ - amount_decimal: string; + message: string; /** - * The computed unit price + * The HTTP status code */ - unit_amount?: number; + status?: number; /** - * The computed unit price as decimal + * The cause of the error (visible for bad requests - http 400) */ - unit_amount_decimal?: string; - } - /** - * Price breakdown - */ - export interface ComputedPriceBreakdown { - static?: /* The computed price components */ ComputedPriceComponents; - variable?: /* The computed price components */ ComputedPriceComponents; - variable_ht?: /* The computed price components */ ComputedPriceComponents; - variable_nt?: /* The computed price components */ ComputedPriceComponents; - } - /** - * The computed price components - */ - export interface ComputedPriceComponents { - [name: string]: /* The computed price */ ComputedBasePrice; - } - /** - * One condition dimension, in the shape a schema's `conditions` array holds it — copy it in - * verbatim. - * - */ - export interface ConditionDefinition { + cause?: string; /** - * How variants and resolve contexts refer to this condition. Independent of attribute - * names: a value needed as an attribute too is duplicated onto the variant. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * - * `default`, and any name beginning with `_`, are reserved for the server: a condition - * declared under one is ignored, since nothing could pin it and no context could address it. + */ + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * - * example: - * postal_code */ - name: string; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "IDENTIFIER_INVALID"; + details: { + /** + * Which id could not be keyed by, named as the request names it. + * example: + * entity_id + */ + field: "entity_id" | "variant_id"; + /** + * Which of the three checks the id failed, in prose. + * example: + * it carries a character this scheme does not admit + */ + reason: string; + }; /** - * Human-readable name of the condition. - * example: - * Postal Code + * Error message */ - label: string; - type: /** - * The kind of value a condition holds, which decides how a variant's pinned value is matched - * against a resolve context. - * - * - `string`: an arbitrary string, matched exactly and case-sensitively - * - `number`: a numeric value - * - `date`: a single date - * - `daterange`: a window with a from and an until timestamp; both ends may be left open - * - `boolean`: a true/false value - * - `select`: one of the values declared in `options`, unless `allow_any` is set - * - `location`: a geographic value, shaped by `format` - * - * There is no condition type for the fallback variant. Being the entity's fallback is a - * property of the variant, set by the `default` flag on a variant write, and needs nothing - * declared in the schema. - * + message: string; + /** + * The HTTP status code */ - ConditionType; + status?: number; /** - * The declared vocabulary of a `select` condition. Absent for every other type. - * - * The same shape a `select` attribute's `options` has on the Entity API, item for item: an - * entry is either the value itself or an object carrying that value and an optional display - * `title`. A `title` is never pinned by a variant and never matched — two entries differing - * only in their title are one vocabulary entry. - * - * Enforced on variant writes, unless `allow_any` is true: a pinned value outside the - * vocabulary is rejected with `CONDITION_VALUE_INVALID`. It is *not* enforced on resolve — - * a vocabulary says what may be stored, not what may be asked for, so a context value - * outside it is a query that simply matches nothing. - * - * example: - * [ - * "private", - * "commercial" - * ] + * The cause of the error (visible for bad requests - http 400) */ - options?: ((string | null) | { - value: string; - title?: string; - })[]; + cause?: string; /** - * Allow arbitrary stored values in addition to the declared `options`. Absent means strict: - * a variant may only pin a declared option. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * - * example: - * false */ - allow_any?: boolean; - /** - * The value shape of a `location` condition. Absent for every other type. + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. + * */ - format?: "zipcode" | "zipcode + town"; - } - /** - * A named bundle of condition definitions, built in for one entity type. - */ - export interface ConditionSet { + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VALID_FROM_INVALID"; + details: { + /** + * What a `valid_from` has to be, in prose. + * example: + * an RFC 3339 date, optionally with a time to at most millisecond precision and an optional UTC offset + */ + expected: string; + }; /** - * Identifies the set within this entity type's catalog. - * example: - * delivery_area + * Error message */ - id: string; + message: string; /** - * Human-readable name of the set. - * example: - * Delivery Area + * The HTTP status code */ - label: string; + status?: number; /** - * What the set is for, and when to reach for it. + * The cause of the error (visible for bad requests - http 400) */ - description: string; + cause?: string; /** - * The condition definitions to copy into the schema's own `conditions` array. - */ - conditions: /** - * One condition dimension, in the shape a schema's `conditions` array holds it — copy it in - * verbatim. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - ConditionDefinition[]; - } - export interface ConditionSetCatalog { - /** - * The condition sets built in for the requested entity type, in the order they are offered. + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - results: /* A named bundle of condition definitions, built in for one entity type. */ ConditionSet[]; - } - /** - * The kind of value a condition holds, which decides how a variant's pinned value is matched - * against a resolve context. - * - * - `string`: an arbitrary string, matched exactly and case-sensitively - * - `number`: a numeric value - * - `date`: a single date - * - `daterange`: a window with a from and an until timestamp; both ends may be left open - * - `boolean`: a true/false value - * - `select`: one of the values declared in `options`, unless `allow_any` is set - * - `location`: a geographic value, shaped by `format` - * - * There is no condition type for the fallback variant. Being the entity's fallback is a - * property of the variant, set by the `default` flag on a variant write, and needs nothing - * declared in the schema. - * - */ - export type ConditionType = "string" | "number" | "date" | "daterange" | "boolean" | "select" | "location"; - /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - export type ConditionalEntitySlug = "product" | "price" | "coupon"; - /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. - * - */ - export interface ConditionalPricingError { + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + code: "VALUE_UNSTORABLE"; + details: { + /** + * Where the value sits, as a dotted path of the request's own keys, with array + * entries by index. + * + * example: + * values.tiers.0.unit_amount + */ + path: string; + /** + * What about the value cannot be stored, in prose. + * example: + * the non-finite number Infinity + */ + reason: string; + }; /** * Error message */ @@ -4383,62 +10673,84 @@ declare namespace Components { */ cause?: string; /** - * The error message. Carries the same string as `message`, which the shared `Error` - * schema requires — `error` is the field responses have always used, and every caller - * to date reads. Declared here rather than on the shared `Error` because a request - * validation failure puts a list of validation errors in this field instead of a - * string, and those responses reference `Error` directly. + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - error?: string; - code?: /** - * Machine-readable failure mode of a conditional-pricing operation, allowing clients - * to branch on the kind of failure instead of parsing the error message. - * - * - `NOT_FOUND` (404): the addressed entity, variant or version does not exist - * - `AMBIGUOUS_RESOLUTION` (409): several variants match the given context while a single result was requested - * - `TUPLE_CONFLICT` (409): the condition tuple is already claimed by another variant - * - `VERSION_CONFLICT` (409): a version already exists at the given `valid_from` on that variant - * - `CONDITION_UNDEFINED` (400): the context names a condition the entity's schema does not define - * - `OPERATOR_UNSUPPORTED` (400): the requested operator is not applicable to the condition's type - * - `CONTEXT_FORMAT_INVALID` (400): a context value is malformed for its condition type - * - `CONDITION_VALUE_INVALID` (400): a variant write pins a `select` value the condition's declared `options` do not contain - * - `TOO_MANY_MATCHES` (400): a multi-match resolve exceeded its result cap - * - `WRITE_CONFLICT` (409): transient write contention, retryable unlike `TUPLE_CONFLICT` - * - * Each code is emitted with the HTTP status shown above, and only with that status. + error?: /** + * What went wrong. The same string as `message`, except on a request-validation + * failure, which puts the list of validation errors here instead. * */ - ConditionalPricingErrorCode; + string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[] | string | { + [name: string]: any; + }[]; + } | { + /** + * Error message + */ + message: string; + /** + * The HTTP status code + */ + status?: number; /** - * Structured data about the failure, shaped by the accompanying `code` - * (e.g. the candidate variants of an `ambiguous-resolution`). Only present - * when the failure has structured data to report, and never without a `code`. + * The cause of the error (visible for bad requests - http 400) + */ + cause?: string; + error?: /** + * The `error` field of an error response: the message, or — where the request failed + * validation before any handler ran — the validation errors themselves. * */ - details?: { - [name: string]: any; - }; - } + ReportedError; + }; /** - * Machine-readable failure mode of a conditional-pricing operation, allowing clients - * to branch on the kind of failure instead of parsing the error message. + * Machine-readable failure mode of a conditional-pricing operation, so a client can branch on + * the kind of failure instead of parsing the message. A `400` is about the request; a `409` is + * about what is already stored. Refusals raised by request validation carry no `code` at all. * - * - `NOT_FOUND` (404): the addressed entity, variant or version does not exist + * - `SCHEMA_NOT_FOUND` (404): no conditional entity type by that slug + * - `ENTITY_NOT_FOUND` (404): the schema holds no entity with that id + * - `ENTITY_TYPE_MISMATCH` (400): that id belongs to an entity of another type than the slug named + * - `ENTITY_NOT_CONDITIONAL` (409): the entity is of the right type but was not created as a conditional one + * - `VARIANT_NOT_FOUND` (404): the entity has no such variant + * - `VERSION_NOT_FOUND` (404): the variant has no version at that `valid_from` + * - `NO_MATCHES` (404): nothing applied to the context and the entity has no `default` variant + * - `NO_ACTIVE_VERSION` (404): the variant has no version in effect at the instant asked about * - `AMBIGUOUS_RESOLUTION` (409): several variants match the given context while a single result was requested * - `TUPLE_CONFLICT` (409): the condition tuple is already claimed by another variant * - `VERSION_CONFLICT` (409): a version already exists at the given `valid_from` on that variant - * - `CONDITION_UNDEFINED` (400): the context names a condition the entity's schema does not define - * - `OPERATOR_UNSUPPORTED` (400): the requested operator is not applicable to the condition's type - * - `CONTEXT_FORMAT_INVALID` (400): a context value is malformed for its condition type - * - `CONDITION_VALUE_INVALID` (400): a variant write pins a `select` value the condition's declared `options` do not contain + * - `CONDITION_UNDEFINED` (400): the request names a condition the entity's schema does not define + * - `VARIANT_PIN_UNDECLARED` (409): a variant a resolve would compose pins a condition the entity's schema no longer declares + * - `OPERATOR_UNSUPPORTED` (400): the requested predicate, or a sort, is not applicable to the condition's type + * - `CONTEXT_FORMAT_INVALID` (400): a resolve context or listing filter value is malformed for its condition type + * - `CONDITION_VALUE_INVALID` (400): a variant write pins a `select` value absent from the condition's declared `options` + * - `CONDITION_UNCONFIGURED` (409): a variant write pins a `select` condition whose `options` are absent or empty * - `TOO_MANY_MATCHES` (400): a multi-match resolve exceeded its result cap * - `WRITE_CONFLICT` (409): transient write contention, retryable unlike `TUPLE_CONFLICT` - * - * Each code is emitted with the HTTP status shown above, and only with that status. + * - `OFFSET_WINDOW_EXCEEDED` (400): a listing's `from` plus `size` reaches past the offset window the search index allows + * - `CURSOR_INVALID` (400): a paging cursor cannot be read, or does not belong to the read it was sent with + * - `VARIANT_LIMIT_REACHED` (409): the entity already holds every variant it may hold + * - `PIN_FORMAT_INVALID` (400): a variant pins a value malformed for its condition's type + * - `VARIANT_UNPINNED` (400): a variant write pins no condition and is not marked `default`, or a batch delete item addresses no variant + * - `LAST_VERSION_UNDELETABLE` (409): the delete would leave the variant with no version at all + * - `CONDITION_UNREADABLE` (409): the entity's schema declares a condition in a way this deploy cannot read + * - `SORT_INVALID` (400): a listing's `sort` is not `conditions.:asc` or `conditions.:desc` + * - `DEFAULT_MARKER_RESERVED` (400): a variant write's pins, or a resolve context, address the fallback marker — `default` or `_default` + * - `DEFAULT_VARIANT_PINS_CONDITIONS` (400): a variant marked `default` also pins real conditions + * - `VALID_FROM_IMMUTABLE` (400): a version write asks for a different `valid_from` than the version its own address names + * - `VARIANT_CONDITIONS_IMMUTABLE` (409): a version write carries a condition tuple other than the one its variant was created with + * - `IDENTIFIER_INVALID` (400): an id in the request cannot be used as a storage key — empty, carrying an unsupported character, or longer than 128 characters + * - `VALID_FROM_INVALID` (400): a `valid_from` is not one of the timestamp forms a version timeline can be sorted by + * - `VALUE_UNSTORABLE` (400): a write carries a value the store cannot hold, such as a non-finite number or one outside the table's numeric range * */ - export type ConditionalPricingErrorCode = "NOT_FOUND" | "AMBIGUOUS_RESOLUTION" | "TUPLE_CONFLICT" | "VERSION_CONFLICT" | "CONDITION_UNDEFINED" | "OPERATOR_UNSUPPORTED" | "CONTEXT_FORMAT_INVALID" | "CONDITION_VALUE_INVALID" | "TOO_MANY_MATCHES" | "WRITE_CONFLICT"; + export type ConditionalPricingErrorCode = "SCHEMA_NOT_FOUND" | "ENTITY_NOT_FOUND" | "ENTITY_TYPE_MISMATCH" | "ENTITY_NOT_CONDITIONAL" | "VARIANT_NOT_FOUND" | "VERSION_NOT_FOUND" | "NO_MATCHES" | "NO_ACTIVE_VERSION" | "AMBIGUOUS_RESOLUTION" | "TUPLE_CONFLICT" | "VERSION_CONFLICT" | "CONDITION_UNDEFINED" | "VARIANT_PIN_UNDECLARED" | "OPERATOR_UNSUPPORTED" | "CONTEXT_FORMAT_INVALID" | "CONDITION_VALUE_INVALID" | "CONDITION_UNCONFIGURED" | "TOO_MANY_MATCHES" | "WRITE_CONFLICT" | "OFFSET_WINDOW_EXCEEDED" | "CURSOR_INVALID" | "VARIANT_LIMIT_REACHED" | "PIN_FORMAT_INVALID" | "VARIANT_UNPINNED" | "LAST_VERSION_UNDELETABLE" | "CONDITION_UNREADABLE" | "SORT_INVALID" | "DEFAULT_MARKER_RESERVED" | "DEFAULT_VARIANT_PINS_CONDITIONS" | "VALID_FROM_IMMUTABLE" | "VARIANT_CONDITIONS_IMMUTABLE" | "IDENTIFIER_INVALID" | "VALID_FROM_INVALID" | "VALUE_UNSTORABLE"; export type ConsumptionTypeGetAg = "household" | "heating_pump" | "night_storage_heating" | "night_storage_heating_common_meter"; /** * The coupon entity @@ -4524,6 +10836,12 @@ declare namespace Components { Currency; cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; active?: boolean; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Whether the coupon requires a promo code to be applied */ @@ -4635,6 +10953,12 @@ declare namespace Components { Currency; cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; active?: boolean; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Whether the coupon requires a promo code to be applied */ @@ -4724,6 +11048,12 @@ declare namespace Components { Currency; cashback_period?: /* The cashback period, for now it's limited to either 0 months or 12 months */ CashbackPeriod; active?: boolean; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Whether the coupon requires a promo code to be applied */ @@ -4765,22 +11095,16 @@ declare namespace Components { } export interface CreateVariantRequest { conditions?: /** - * The situation this variant applies to: a flat map keyed by condition name, as the entity's - * schema declares them. A condition left out is a wildcard — the variant applies whatever the - * context says for it, which is what makes adding a condition to a schema non-breaking for the - * variants that already exist. + * The situation this variant applies to: a flat map keyed by condition name. A condition left + * out is a wildcard, which is what makes adding a condition to a schema non-breaking for + * existing variants. * - * Exact values only. Predicates are accepted in a resolve context and nowhere else, so that - * matching is decided in exactly one place. + * Exact values only; predicates belong to reads. Values are stored canonicalized for their + * type: a `date` becomes millisecond-precision UTC, a `daterange` an object carrying `from` + * and `until` where an empty string is an open end, a `location` of format `zipcode` the + * postal code itself and one of format `zipcode_town` an object carrying both. * - * Values are typed by their condition and stored canonicalized for that type: a `date` becomes - * millisecond-precision UTC, a `daterange` an object carrying `from` and `until` where an empty - * string is an open end, a `location` of format `zipcode` the postal code itself and one of - * format `zipcode + town` an object carrying both. A `select` value must be a string, and must - * be one the condition's `options` declare unless it sets `allow_any`. - * - * `default`, and any name beginning with `_`, are reserved for the server and cannot be pinned - * here. Whether a variant is the entity's fallback is set through the request's `default` flag. + * `default` and names beginning with `_` are reserved; use the request's `default` flag. * * example: * { @@ -4789,47 +11113,34 @@ declare namespace Components { */ PinnedConditions; /** - * Mark this variant as the entity's fallback: the one served when no other variant applies. - * - * A property of the variant, never an entry in `conditions` — a variant claiming a value for - * the marker would hold a real condition tuple while being permanently unmatchable, since no - * resolve context ever supplies it. A default variant cannot pin anything else, and an - * entity can have at most one. - * - * Available to every conditional entity: nothing has to be declared in the schema first. - * The variant is stored pinning one reserved condition, which is what makes the ordinary - * condition-tuple guard enforce at-most-one-per-entity with no rule of its own. + * Mark this variant as the entity's fallback, served when no other variant applies. It can + * pin nothing else, and an entity may have one; a second is `TUPLE_CONFLICT`. Available to + * every conditional entity without anything being declared in the schema. * */ default?: boolean; /** - * When the first version takes effect. Defaults to now. - * - * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time - * (`2026-01-01T00:00:00Z`), to at most millisecond precision. Deliberately not declared as - * `format: date-time`, which would reject the plain-date form that this accepts. + * When the first version takes effect. Defaults to now. An RFC 3339 date (`2026-01-01`, + * read as midnight UTC) or date-time, to at most millisecond precision. * * example: * 2027-01-01T00:00:00Z */ valid_from?: string; values: /** - * The attribute values this version overrides on the base entity, keyed by attribute name. + * The values this version overrides on the base entity, keyed by entity field name. * - * Only attributes currently declaring `overridable_attribute` are applied. Metadata fields - * (anything underscore-prefixed), readonly attributes, hidden attributes and non-overridable - * attributes present here are ignored rather than rejected, so a client working from a slightly - * stale schema snapshot still succeeds instead of failing on fields it could not have known to - * drop. An attribute's `render_condition` says when to show it and has no bearing on whether a - * variant may override it. + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. * - * Ignored means *not updated*, never *removed*: a value already stored for an attribute that is - * not currently overridable is preserved, so removing and restoring the flag deactivates and - * then reactivates the same override. + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. * - * A composite price's `price_components` is an ordinary overridable relation attribute: a - * composite variant pins its component variants here the same way any other relation value is - * set, with no special handling. + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. * * example: * { @@ -4841,10 +11152,7 @@ declare namespace Components { } export interface CreatedVariant { /** - * Server-generated, always. This is the durable key orders and contracts pin, so it is never - * accepted from a client — a client-suppliable id would risk collisions between independent - * importers. - * + * Server-generated. The durable key orders and contracts pin. * example: * var-46045 */ @@ -4854,16 +11162,9 @@ declare namespace Components { * price-sp26d1yo */ entity_id: string; - schema: /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - ConditionalEntitySlug; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; /** - * The situation this variant applies to, plus the boolean `default` discriminator — the - * same shape `_conditions` has on a resolved payload. - * + * The situation this variant applies to, plus the boolean `default` discriminator. * example: * { * "postal_code": "46045", @@ -4881,22 +11182,19 @@ declare namespace Components { */ valid_from: string; values: /** - * The attribute values this version overrides on the base entity, keyed by attribute name. + * The values this version overrides on the base entity, keyed by entity field name. * - * Only attributes currently declaring `overridable_attribute` are applied. Metadata fields - * (anything underscore-prefixed), readonly attributes, hidden attributes and non-overridable - * attributes present here are ignored rather than rejected, so a client working from a slightly - * stale schema snapshot still succeeds instead of failing on fields it could not have known to - * drop. An attribute's `render_condition` says when to show it and has no bearing on whether a - * variant may override it. + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. * - * Ignored means *not updated*, never *removed*: a value already stored for an attribute that is - * not currently overridable is preserved, so removing and restoring the flag deactivates and - * then reactivates the same override. + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. * - * A composite price's `price_components` is an ordinary overridable relation attribute: a - * composite variant pins its component variants here the same way any other relation value is - * set, with no special handling. + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. * * example: * { @@ -4914,17 +11212,18 @@ declare namespace Components { */ _updated_at: string; /** - * The revision a later write to this version must carry to be accepted. Genuinely current, - * unlike one read back later from an eventually-consistent read. - * + * The revision a later write to this version must carry. */ _revision: number; /** - * Things worth knowing that did not stop the write. Empty in the ordinary case — a client - * reads its length rather than branching on its absence. + * Things worth knowing that did not stop the write. Always present, and empty in the ordinary case. + */ + warnings: /** + * Something worth knowing that did not stop a write. One vocabulary for every write; `details` + * is typed per `code`, and a write raises each code at most once. * */ - warnings: VariantWriteWarning[]; + WriteWarning[]; } /** * Three-letter ISO currency code, in lowercase. Must be a supported currency. @@ -4966,16 +11265,10 @@ declare namespace Components { * price-sp26d1yo */ entity_id: string; - schema: /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - ConditionalEntitySlug; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; /** - * Whether this call is the one that freed the variant's combination of condition values. - * `false` where an earlier, interrupted attempt had already freed it — the delete still - * succeeded, and the combination was already reusable. + * Whether this call freed the variant's combination of condition values. `false` where an + * earlier, interrupted attempt had already freed it. * */ tuple_released: boolean; @@ -4995,12 +11288,7 @@ declare namespace Components { * price-sp26d1yo */ entity_id: string; - schema: /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - ConditionalEntitySlug; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; /** * The version removed, canonicalized to millisecond-precision UTC. * example: @@ -5008,16 +11296,14 @@ declare namespace Components { */ valid_from: string; /** - * What the delete moved, if anything. Empty when a scheduled version was withdrawn. + * What the delete moved. Always present, and empty when a scheduled version was withdrawn. */ warnings: /** - * Something a version write moved. A version write is never refused for being late — backdating a - * version, and editing or deleting one that has already been superseded, are both accepted — so - * what a caller gets instead is a warning naming exactly what changed. One write can carry both - * codes. + * Something worth knowing that did not stop a write. One vocabulary for every write; `details` + * is typed per `code`, and a write raises each code at most once. * */ - VersionWriteWarning[]; + WriteWarning[]; } export interface DiscountAmounts { /** @@ -5788,6 +12074,12 @@ declare namespace Components { * The flag for prices that contain price components. */ is_composite_price: true; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * The price creation date */ @@ -5813,6 +12105,49 @@ declare namespace Components { */ _tags?: string[]; } + /** + * One override that did not apply, and why — reported by a write for the attributes in its + * body, and by a resolved payload for the stored overrides composition passed over. + * + */ + export interface InertOverride { + /** + * The attribute's name, as the request body or the stored version spells it. + * example: + * unit_amount + */ + attribute: string; + reason: /** + * Why one override did not apply. + * + * - `ATTRIBUTE_NOT_OVERRIDABLE`: the schema declares the attribute without + * `overridable_attribute`, which is an ordinary schema edit away + * - `ATTRIBUTE_READONLY`: the attribute is readonly, and cannot be granted the flag + * - `ATTRIBUTE_HIDDEN`: the attribute is hidden, and cannot be granted the flag + * - `ATTRIBUTE_COMPUTED`: the attribute's value is derived rather than stored + * - `ATTRIBUTE_UNDECLARED`: the schema declares no attribute of that name + * - `TYPE_NOT_OVERRIDABLE`: the attribute's type is not one a variant may override + * - `CAPABILITY_NOT_OVERRIDABLE`: the field is managed by a capability that does not declare + * `overridable_attribute` + * + */ + InertOverrideReason; + } + /** + * Why one override did not apply. + * + * - `ATTRIBUTE_NOT_OVERRIDABLE`: the schema declares the attribute without + * `overridable_attribute`, which is an ordinary schema edit away + * - `ATTRIBUTE_READONLY`: the attribute is readonly, and cannot be granted the flag + * - `ATTRIBUTE_HIDDEN`: the attribute is hidden, and cannot be granted the flag + * - `ATTRIBUTE_COMPUTED`: the attribute's value is derived rather than stored + * - `ATTRIBUTE_UNDECLARED`: the schema declares no attribute of that name + * - `TYPE_NOT_OVERRIDABLE`: the attribute's type is not one a variant may override + * - `CAPABILITY_NOT_OVERRIDABLE`: the field is managed by a capability that does not declare + * `overridable_attribute` + * + */ + export type InertOverrideReason = "ATTRIBUTE_NOT_OVERRIDABLE" | "ATTRIBUTE_READONLY" | "ATTRIBUTE_HIDDEN" | "ATTRIBUTE_COMPUTED" | "ATTRIBUTE_UNDECLARED" | "TYPE_NOT_OVERRIDABLE" | "CAPABILITY_NOT_OVERRIDABLE"; /** * The auth credentials for external integrations */ @@ -5890,6 +12225,72 @@ declare namespace Components { }; }[]; } + /** + * How to narrow and page a variant listing. Every property is optional, so `{}` asks for the + * first ten variants in `variant_id` order, but the body itself is required. `conditions` and + * `search` narrow independently and a variant must satisfy both. + * + */ + export interface ListVariantsRequest { + conditions?: /** + * Which pins a variant must carry to be listed: a flat map keyed by condition name, taking the + * same exact values and predicates a resolve context does. A condition left out is not + * filtered on. An `in` list carries at most 50,000 values. + * + * A variant matches only where it pins the condition — unlike `:resolve`, where an unpinned + * condition matches any value. `{ "exists": false }` selects the variants that leave it + * unpinned. + * + * `default` is accepted as an exact boolean and takes no predicate: `true` selects the + * entity's fallback variant, `false` every variant that is not it. Names beginning with `_` + * are reserved. + * + * example: + * { + * "postal_code": "46045", + * "consumption": { + * "lt": 5000 + * } + * } + */ + VariantConditionFilter; + /** + * Free text matched against the scalar pins — `string`, `select`, `number` and `date`. + * `location` and `daterange` pins are stored structured and are not matched. + * + * example: + * 460 + */ + search?: string; + /** + * `conditions.:asc` or `conditions.:desc`, for a `string`, `select`, `number` + * or `date` pin. `variant_id:asc` is always appended, so the order is total. + * + * example: + * conditions.postal_code:asc + */ + sort?: string; + /** + * The offset to read from, ignored when a `cursor` is sent. Bounded together with `size` + * by the search index's offset window; a page reaching past it is + * `OFFSET_WINDOW_EXCEEDED`, which reports the window. + * + */ + from?: number; + /** + * Rows per page. Clamped silently at 1000. + */ + size?: number; + /** + * Continue from a previous response's `next`, which is where a caller goes when the offset + * window runs out. Opaque, and valid only with the `conditions`, `search` and `sort` it + * was issued with. + * + * example: + * eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0 + */ + cursor?: string; + } /** * Market participant data */ @@ -6088,6 +12489,12 @@ declare namespace Components { * The flag for prices that contain price components. */ is_composite_price: true; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * The price creation date */ @@ -7264,10 +13671,8 @@ declare namespace Components { export type OrderStatus = "draft" | "quote" | "placed" | "cancelled" | "completed"; export interface PatchVersionRequest { /** - * Only the attribute overrides to change. Everything not mentioned is left as stored. - * - * `null` is a value like any other here rather than a deletion; to stop overriding an - * attribute, send the complete snapshot without it through the replace operation. + * Only the overrides to change; everything not mentioned is left as stored. `null` sets a + * value rather than removing an override — use the replace operation to remove one. * * example: * { @@ -7279,21 +13684,19 @@ declare namespace Components { [name: string]: any; }; /** - * The revision marker read from the version being written. The write is refused with - * `WRITE_CONFLICT` if the version has been written since. + * The revision read from the version being written. Refused with `WRITE_CONFLICT` if the + * version has been written since. * * example: * 3 */ _revision: number; /** - * Optional, never applied, and refused when it names a version other than the one addressed. + * Accepted only when it names the version being addressed. */ valid_from?: string; /** - * Optional, and never applied. A partial update that tries to change a pinned condition value - * is refused — this is the path that rule is most likely to be broken on by accident. - * + * Accepted only unchanged. A variant's conditions are fixed when it is created. * example: * { * "postal_code": "46045" @@ -7320,22 +13723,16 @@ declare namespace Components { }; } /** - * The situation this variant applies to: a flat map keyed by condition name, as the entity's - * schema declares them. A condition left out is a wildcard — the variant applies whatever the - * context says for it, which is what makes adding a condition to a schema non-breaking for the - * variants that already exist. - * - * Exact values only. Predicates are accepted in a resolve context and nowhere else, so that - * matching is decided in exactly one place. + * The situation this variant applies to: a flat map keyed by condition name. A condition left + * out is a wildcard, which is what makes adding a condition to a schema non-breaking for + * existing variants. * - * Values are typed by their condition and stored canonicalized for that type: a `date` becomes - * millisecond-precision UTC, a `daterange` an object carrying `from` and `until` where an empty - * string is an open end, a `location` of format `zipcode` the postal code itself and one of - * format `zipcode + town` an object carrying both. A `select` value must be a string, and must - * be one the condition's `options` declare unless it sets `allow_any`. + * Exact values only; predicates belong to reads. Values are stored canonicalized for their + * type: a `date` becomes millisecond-precision UTC, a `daterange` an object carrying `from` + * and `until` where an empty string is an open end, a `location` of format `zipcode` the + * postal code itself and one of format `zipcode_town` an object carrying both. * - * `default`, and any name beginning with `_`, are reserved for the server and cannot be pinned - * here. Whether a variant is the entity's fallback is set through the request's `default` flag. + * `default` and names beginning with `_` are reserved; use the request's `default` flag. * * example: * { @@ -7345,6 +13742,23 @@ declare namespace Components { export interface PinnedConditions { [name: string]: any; } + /** + * The options a pinned resolve accepts — `hydrate` and nothing else. `resolve_one` has nothing + * to change where the answer is one result or a 404, so a body sending it is a `400`. + * + */ + export interface PinnedResolveOptions { + /** + * Return the entities a relation attribute references in place of the references, one + * level deep, as an entity read with hydration does. Applied after composition, so a + * relation this variant's version replaced is hydrated too. + * + * A referenced entity that is itself conditional is returned unresolved, carrying its own + * flag. Costs one fetch per distinct referenced entity, with no per-attribute limit. + * + */ + hydrate?: boolean; + } export interface PortalContext { [name: string]: any; /** @@ -7495,6 +13909,12 @@ declare namespace Components { * The flag for prices that contain price components. */ is_composite_price?: false; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Describes how to compute the price per period. Either `per_unit`, `tiered_graduated` or `tiered_volume`. * - `per_unit` indicates that the fixed amount (specified in unit_amount or unit_amount_decimal) will be charged per unit in quantity @@ -8180,6 +14600,12 @@ declare namespace Components { price_options?: { $relation?: EntityRelation[]; }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Stores references to the availability files that define where this product is available. * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. @@ -8578,6 +15004,12 @@ declare namespace Components { price_options?: { $relation?: EntityRelation[]; }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Stores references to the availability files that define where this product is available. * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. @@ -8750,6 +15182,12 @@ declare namespace Components { * The flag for prices that contain price components. */ is_composite_price?: false; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Describes how to compute the price per period. Either `per_unit`, `tiered_graduated` or `tiered_volume`. * - `per_unit` indicates that the fixed amount (specified in unit_amount or unit_amount_decimal) will be charged per unit in quantity @@ -9599,6 +16037,12 @@ declare namespace Components { price_options?: { $relation?: EntityRelation[]; }; + /** + * The flag for entities whose values vary by context. Resolve the values that apply with + * `POST /v1/conditional-pricing:resolve`. + * + */ + is_conditional?: boolean; /** * Stores references to the availability files that define where this product is available. * These files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block. @@ -10350,13 +16794,8 @@ declare namespace Components { } export interface ReplaceVersionRequest { /** - * The complete set of attribute overrides this version carries. An overridable attribute - * absent from here stops being overridden. - * - * Attributes the variant may not override are ignored where this carries them, and their - * **stored value is kept rather than dropped** — otherwise a routine full-snapshot write - * would erase an override the moment its attribute's `overridable_attribute`, `readonly` or - * `hidden` flag happened to be off. + * The complete set of overrides this version carries. An overridable attribute absent from + * here stops being overridden; one the variant may not override keeps its stored value. * * example: * { @@ -10368,29 +16807,21 @@ declare namespace Components { [name: string]: any; }; /** - * The revision marker read from the version being written. The write is refused with - * `WRITE_CONFLICT` if the version has been written since. - * - * Required rather than optional: an optional one is a guarantee every client can opt out of - * by forgetting a field, and the write it protects is the one that overwrites somebody - * else's edit. + * The revision read from the version being written. Refused with `WRITE_CONFLICT` if the + * version has been written since. * * example: * 3 */ _revision: number; /** - * Optional, and never applied. Accepted when it names the version being addressed — so a - * client building its body from what it loaded need not strip it out — and refused when it - * names another: a version's `valid_from` is its identity, and moving it is an append and a - * delete rather than an edit. + * Accepted only when it names the version being addressed. Moving a version is an append + * and a delete. * */ valid_from?: string; /** - * Optional, and never applied: a variant's conditions are fixed when it is created. Refused - * when they describe a different situation from the stored one. - * + * Accepted only unchanged. A variant's conditions are fixed when it is created. * example: * { * "postal_code": "46045" @@ -10400,90 +16831,151 @@ declare namespace Components { [name: string]: any; }; } - export interface ResolveConditionalEntityRequest { - schema: /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. + /** + * The `error` field of an error response: the message, or — where the request failed + * validation before any handler ran — the validation errors themselves. + * + */ + export type ReportedError = /** + * The `error` field of an error response: the message, or — where the request failed + * validation before any handler ran — the validation errors themselves. + * + */ + string | { + [name: string]: any; + }[]; + /** + * Resolve by matching a situation: which of this entity's variants apply to `context`, each + * composed with the version in effect at `as_of`. + * + */ + export interface ResolveByContextRequest { + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; + /** + * The conditional entity to resolve. Resolution is always scoped to exactly one. + * example: + * price-sp26d1yo + */ + entity_id: string; + context: /** + * The situation to resolve for: a flat map keyed by condition name. A condition left out + * matches only variants that leave it unpinned; an empty map therefore returns the `default` + * variant. + * + * Each value is an exact value, typed by its condition, or a single-operator predicate: + * + * - `{ "lt": v }`, `{ "lte": v }`, `{ "gt": v }`, `{ "gte": v }` — order, against a `number` + * or `date` condition + * - `{ "in": [...] }` — membership, against a `string`, `select` or `number` condition + * - `{ "between": "2026-03-01" }` — `daterange` containment, which a plain date also means + * - `{ "exists": true }` — pinned to any value; `{ "exists": false }` — left unpinned + * + * An `in` list carries at most 50,000 values. A `string` or `select` matches exactly and + * case-sensitively. A `location` of format + * `zipcode` is the postal code itself; one of format `zipcode_town` is an object carrying + * both, whose town is compared case- and whitespace-insensitively. + * + * `default` and names beginning with `_` are reserved and cannot be supplied. + * + * example: + * { + * "postal_code": "46045", + * "consumption": { + * "lt": 5000 + * } + * } + */ + ResolveContext; + /** + * The instant the version is selected at — the version with the latest `valid_from` at or + * before it. Defaults to now. A variant whose first version is later is excluded from + * matching; a pin naming one is answered `NO_ACTIVE_VERSION` instead. + * + * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most + * millisecond precision. * + * example: + * 2027-03-15T00:00:00Z */ - ConditionalEntitySlug; + as_of?: string; + options?: /* The options a context resolve accepts. A pin takes `PinnedResolveOptions` instead. */ ResolveOptions; + } + /** + * Resolve by naming a variant: compose this one, whatever a context would have matched. + */ + export interface ResolveByPinRequest { + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; /** * The conditional entity to resolve. Resolution is always scoped to exactly one. * example: * price-sp26d1yo */ entity_id: string; - context?: /** - * The situation to resolve for: a flat map keyed by condition name, as the entity's schema - * declares them. A condition left out of the map is not a wildcard — it matches only variants - * that leave that condition unpinned. - * - * Each value is either an exact value, typed by its condition, or a single-operator predicate - * object: - * - * - `{ "lt": v }`, `{ "lte": v }`, `{ "gt": v }`, `{ "gte": v }` — order against a `number` or - * `date` condition. - * - `{ "in": [...] }` — membership, against a `string`, `select` or `number` condition. - * - `{ "between": "2026-03-01" }` — the explicit spelling of `daterange` containment; a plain - * date supplied for a `daterange` condition means the same thing. - * - `{ "exists": true }` — pinned to any value. `{ "exists": false }` says what leaving the key - * out says. - * - * Exact values are typed by their condition: a `string` or `select` matches exactly and - * case-sensitively, with no trimming; a `location` of format `zipcode` is the postal code - * itself, and one of format `zipcode + town` an object carrying both, whose town is compared - * case- and whitespace-insensitively while its postal code is not. - * - * `default`, and any name beginning with `_`, are reserved for the server and cannot be - * supplied here. + /** + * The variant to compose. Condition matching is skipped, the `default` fallback does not + * apply, and `results` carries exactly one entry. A variant of another entity is + * `VARIANT_NOT_FOUND`. * * example: - * { - * "postal_code": "46045", - * "consumption": { - * "lt": 5000 - * } - * } + * var-46045 */ - ResolveContext; + variant_id: string; /** * The instant the version is selected at — the version with the latest `valid_from` at or - * before it. Defaults to now. A variant whose first version is later than this is - * scheduled rather than applicable, and is excluded from resolution entirely. + * before it. Defaults to now. A pinned variant whose first version is later is + * `NO_ACTIVE_VERSION`, carrying the instant in `details.as_of`. * - * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time - * (`2026-01-01T00:00:00Z`), to at most millisecond precision. Deliberately not declared as - * `format: date-time`, which would reject the plain-date form that this accepts. + * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most + * millisecond precision. * * example: * 2027-03-15T00:00:00Z */ as_of?: string; - options?: ResolveOptions; + options?: /** + * The options a pinned resolve accepts — `hydrate` and nothing else. `resolve_one` has nothing + * to change where the answer is one result or a 404, so a body sending it is a `400`. + * + */ + PinnedResolveOptions; } /** - * The situation to resolve for: a flat map keyed by condition name, as the entity's schema - * declares them. A condition left out of the map is not a wildcard — it matches only variants - * that leave that condition unpinned. + * A resolve names one conditional entity and selects its variants either by `context` or by + * `variant_id`, never both. `context: {}` matches nothing and so returns the `default` + * variant, which is how to ask for it without knowing its id. * - * Each value is either an exact value, typed by its condition, or a single-operator predicate - * object: + */ + export type ResolveConditionalEntityRequest = /** + * A resolve names one conditional entity and selects its variants either by `context` or by + * `variant_id`, never both. `context: {}` matches nothing and so returns the `default` + * variant, which is how to ask for it without knowing its id. + * + */ + /** + * Resolve by matching a situation: which of this entity's variants apply to `context`, each + * composed with the version in effect at `as_of`. + * + */ + ResolveByContextRequest | /* Resolve by naming a variant: compose this one, whatever a context would have matched. */ ResolveByPinRequest; + /** + * The situation to resolve for: a flat map keyed by condition name. A condition left out + * matches only variants that leave it unpinned; an empty map therefore returns the `default` + * variant. + * + * Each value is an exact value, typed by its condition, or a single-operator predicate: * - * - `{ "lt": v }`, `{ "lte": v }`, `{ "gt": v }`, `{ "gte": v }` — order against a `number` or - * `date` condition. - * - `{ "in": [...] }` — membership, against a `string`, `select` or `number` condition. - * - `{ "between": "2026-03-01" }` — the explicit spelling of `daterange` containment; a plain - * date supplied for a `daterange` condition means the same thing. - * - `{ "exists": true }` — pinned to any value. `{ "exists": false }` says what leaving the key - * out says. + * - `{ "lt": v }`, `{ "lte": v }`, `{ "gt": v }`, `{ "gte": v }` — order, against a `number` + * or `date` condition + * - `{ "in": [...] }` — membership, against a `string`, `select` or `number` condition + * - `{ "between": "2026-03-01" }` — `daterange` containment, which a plain date also means + * - `{ "exists": true }` — pinned to any value; `{ "exists": false }` — left unpinned * - * Exact values are typed by their condition: a `string` or `select` matches exactly and - * case-sensitively, with no trimming; a `location` of format `zipcode` is the postal code - * itself, and one of format `zipcode + town` an object carrying both, whose town is compared - * case- and whitespace-insensitively while its postal code is not. + * An `in` list carries at most 50,000 values. A `string` or `select` matches exactly and + * case-sensitively. A `location` of format + * `zipcode` is the postal code itself; one of format `zipcode_town` is an object carrying + * both, whose town is compared case- and whitespace-insensitively. * - * `default`, and any name beginning with `_`, are reserved for the server and cannot be - * supplied here. + * `default` and names beginning with `_` are reserved and cannot be supplied. * * example: * { @@ -10496,35 +16988,42 @@ declare namespace Components { export interface ResolveContext { [name: string]: any; } + /** + * The options a context resolve accepts. A pin takes `PinnedResolveOptions` instead. + */ export interface ResolveOptions { /** - * Ask for an unambiguous answer. Several applicable variants become `AMBIGUOUS_RESOLUTION` - * rather than a set, and nothing applicable becomes `NOT_FOUND` rather than an empty one. - * The response shape does not change: `results` simply carries exactly one entry. + * Ask for an unambiguous answer: several applicable variants become + * `AMBIGUOUS_RESOLUTION`, and none becomes `NO_MATCHES`. * */ resolve_one?: boolean; + /** + * Return the entities a relation attribute references in place of the references, one + * level deep, as an entity read with hydration does. Applied after composition, so a + * relation this variant's version replaced is hydrated too. + * + * A referenced entity that is itself conditional is returned unresolved, carrying its own + * flag. Costs one fetch per distinct referenced entity, with no per-attribute limit. + * + */ + hydrate?: boolean; } /** - * The entity as this variant leaves it — every attribute of a plain entity read, with the - * applicable version's overrides applied — plus the discriminators saying where the numbers - * came from. + * The entity as this variant leaves it — every attribute of a plain entity read with the + * applicable version's overrides applied — plus the discriminators below. * */ export interface ResolvedVariant { [name: string]: any; /** - * The logical entity's id — the same one a plain entity read returns. Resolution never - * mints a new identity; a variant is a set of values for *this* entity, not another one. - * + * The logical entity's id, the same one a plain entity read returns. * example: * price-sp26d1yo */ _id: string; /** - * The variant these values came from. Durable: this is what an order or a contract pins to - * read the same numbers back later. - * + * The variant these values came from — what an order or contract pins. * example: * var-46045 */ @@ -10537,10 +17036,6 @@ declare namespace Components { _version_valid_from: string; /** * The conditions this variant pins, plus the boolean `default` discriminator. - * - * Underscore-prefixed, like every other discriminator here, so that it cannot collide with - * an attribute an organization happens to have called `conditions`. - * * example: * { * "postal_code": "46045", @@ -10551,18 +17046,29 @@ declare namespace Components { [name: string]: any; default: boolean; }; + /** + * The variant's stored overrides this payload did not apply, and why. Always present, and + * empty in the ordinary case. Computed per read against the schema as it stands, so + * granting or withdrawing `overridable_attribute` changes it without any data being + * rewritten. + * + */ + _inert_overrides: /** + * One override that did not apply, and why — reported by a write for the attributes in its + * body, and by a resolved payload for the stored overrides composition passed over. + * + */ + InertOverride[]; } export interface ResolvedVariants { /** - * One composed payload per applicable variant, capped at 100 — a context selecting more - * than that is answered with `TOO_MANY_MATCHES` instead, since each result costs its own - * version lookup. No dominance or specificity ordering is applied between them. + * One composed payload per applicable variant, capped at 100 — a context selecting more is + * `TOO_MANY_MATCHES`. Unordered. * */ results: /** - * The entity as this variant leaves it — every attribute of a plain entity read, with the - * applicable version's overrides applied — plus the discriminators saying where the numbers - * came from. + * The entity as this variant leaves it — every attribute of a plain entity read with the + * applicable version's overrides applied — plus the discriminators below. * */ ResolvedVariant[]; @@ -10896,95 +17402,373 @@ declare namespace Components { */ taxes?: (/* A tax amount associated with a specific tax rate. */ TaxAmountBreakdown)[]; /** - * The aggregated price items tax amount per rate. + * The aggregated price items tax amount per rate. + */ + recurrences?: (/* An amount associated with a specific recurrence. */ RecurrenceAmount)[]; + /** + * The list of cashbacks applied. + */ + cashbacks?: (/* A detail associated with a specific cashback. */ CashbackAmount)[]; + /** + * The aggregated price items recurrences by tax rate + */ + recurrencesByTax?: (/* An amount associated with a specific recurrence. */ RecurrenceAmountWithTax)[]; + }; + } + export type TypeGetAg = "base_price" | "work_price"; + /** + * The availability rule error + */ + export interface ValidateAvailabilityFileError { + /** + * The line number where the error was found + */ + line?: number; + /** + * The error message + */ + msg: string; + /** + * Data related to the error + */ + data?: string; + } + /** + * The availability map file result payload + * example: + * { + * "status": "success", + * "rules_parsed_count": 10, + * "errors": [] + * } + */ + export interface ValidateAvailabilityFileResult { + /** + * The status of the validation + */ + status: "success" | "error"; + /** + * The number of rules successfully parsed + */ + rules_parsed_count: number; + /** + * The errors found on the file + */ + errors: /* The availability rule error */ ValidateAvailabilityFileError[]; + } + /** + * Which pins a variant must carry to be listed: a flat map keyed by condition name, taking the + * same exact values and predicates a resolve context does. A condition left out is not + * filtered on. An `in` list carries at most 50,000 values. + * + * A variant matches only where it pins the condition — unlike `:resolve`, where an unpinned + * condition matches any value. `{ "exists": false }` selects the variants that leave it + * unpinned. + * + * `default` is accepted as an exact boolean and takes no predicate: `true` selects the + * entity's fallback variant, `false` every variant that is not it. Names beginning with `_` + * are reserved. + * + * example: + * { + * "postal_code": "46045", + * "consumption": { + * "lt": 5000 + * } + * } + */ + export interface VariantConditionFilter { + [name: string]: any; + } + /** + * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a + * boolean `default` saying whether this is the entity's fallback. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + export interface VariantConditions { + [name: string]: any; + default: boolean; + } + export interface VariantList { + /** + * How many variants match in total, exactly — not how many this page carries. + * example: + * 8128 + */ + hits: number; + results: /* One variant as a listing reports it: which variant it is and what it pins. */ VariantListRow[]; + /** + * The cursor that continues this listing, absent on the last page. Send it back as + * `cursor`, with the same filter, search and sort. + * + * example: + * eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0 + */ + next?: string; + } + /** + * One variant as a listing reports it: which variant it is and what it pins. + */ + export interface VariantListRow { + /** + * example: + * var-46045 + */ + variant_id: string; + /** + * example: + * price-sp26d1yo + */ + entity_id: string; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; + /** + * The situation this variant applies to, plus the boolean `default` discriminator. + * Membership of a page may lag a write by moments; the pins themselves never do. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + conditions: { + [name: string]: any; + default: boolean; + }; + } + export interface VariantTree { + /** + * How many variants match in total, exactly — not how many this page carries. + * example: + * 8128 + */ + hits: number; + /** + * One row per matching variant, in the requested order. A variant mid-delete is omitted, + * so `results` can be shorter than `hits` implies. + * + */ + results: /* A listing row plus the one version the tree shows for it, and the status saying which. */ VariantTreeRow[]; + /** + * The cursor that continues this listing, absent on the last page. Send it back as + * `cursor`, with the same filter, search and sort; `as_of` may change between pages. + * + * example: + * eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0 + */ + next?: string; + } + /** + * The variants list's request plus `as_of`, the instant each row's version is selected at. + * `size` is clamped at 100 here; every other property means what it means on the list. + * + */ + export interface VariantTreeRequest { + conditions?: /** + * Which pins a variant must carry to be listed: a flat map keyed by condition name, taking the + * same exact values and predicates a resolve context does. A condition left out is not + * filtered on. An `in` list carries at most 50,000 values. + * + * A variant matches only where it pins the condition — unlike `:resolve`, where an unpinned + * condition matches any value. `{ "exists": false }` selects the variants that leave it + * unpinned. + * + * `default` is accepted as an exact boolean and takes no predicate: `true` selects the + * entity's fallback variant, `false` every variant that is not it. Names beginning with `_` + * are reserved. + * + * example: + * { + * "postal_code": "46045", + * "consumption": { + * "lt": 5000 + * } + * } + */ + VariantConditionFilter; + /** + * Free text matched against the scalar pins — `string`, `select`, `number` and `date`. + * `location` and `daterange` pins are stored structured and are not matched. + * + * example: + * 460 + */ + search?: string; + /** + * `conditions.:asc` or `conditions.:desc`, for a `string`, `select`, `number` + * or `date` pin. `variant_id:asc` is always appended, so the order is total. + * + * example: + * conditions.postal_code:asc + */ + sort?: string; + /** + * The offset to read from, ignored when a `cursor` is sent. Bounded together with `size` + * by the search index's offset window; a page reaching past it is + * `OFFSET_WINDOW_EXCEEDED`, which reports the window. + * + */ + from?: number; + /** + * Rows per page. Clamped silently at 100, since every row costs its own version lookup. + */ + size?: number; + /** + * Continue from a previous response's `next`, which is where a caller goes when the offset + * window runs out. Opaque, and valid only with the `conditions`, `search` and `sort` it + * was issued with. + * + * example: + * eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0 + */ + cursor?: string; + /** + * The instant each row's version is selected at. Defaults to now. A variant whose first + * version is later is a row with `status: scheduled` carrying that upcoming version. + * + * An RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most + * millisecond precision. + * + * example: + * 2027-03-15T00:00:00Z + */ + as_of?: string; + } + /** + * A listing row plus the one version the tree shows for it, and the status saying which. + */ + export interface VariantTreeRow { + /** + * example: + * var-46045 + */ + variant_id: string; + /** + * example: + * price-sp26d1yo + */ + entity_id: string; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; + /** + * The situation this variant applies to, plus the boolean `default` discriminator. + * Membership of a page may lag a write by moments; the pins themselves never do. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + conditions: { + [name: string]: any; + default: boolean; + }; + status: /** + * Whether a tree row's version is the one in effect at `as_of`, or one still ahead of it. + * + * - `active`: the version with the latest `valid_from` at or before `as_of` + * - `scheduled`: the variant's first version, which is later than `as_of` + * + */ + VariantTreeRowStatus; + /** + * The version in effect at `as_of`, or the variant's upcoming first one where every + * version is still ahead of it. `status` says which. Always present. + * + */ + version: { + /** + * example: + * var-46045 + */ + variant_id: string; + /** + * example: + * price-sp26d1yo + */ + entity_id: string; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; + /** + * The situation the variant applies to, plus the boolean `default` discriminator. A + * property of the variant: every version carries the same one. + * + * example: + * { + * "postal_code": "46045", + * "default": false + * } + */ + conditions: { + [name: string]: any; + default: boolean; + }; + /** + * When this version takes effect, canonicalized to millisecond-precision UTC. Its identity + * within the variant. + * + * example: + * 2027-01-01T00:00:00.000Z */ - recurrences?: (/* An amount associated with a specific recurrence. */ RecurrenceAmount)[]; + valid_from: string; + values: /** + * The values this version overrides on the base entity, keyed by entity field name. + * + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. + * + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. + * + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. + * + * example: + * { + * "unit_amount": 2499, + * "unit_amount_decimal": "24.99" + * } + */ + VariantValues; /** - * The list of cashbacks applied. + * When this version was created. */ - cashbacks?: (/* A detail associated with a specific cashback. */ CashbackAmount)[]; + _created_at: string; /** - * The aggregated price items recurrences by tax rate + * When this version was last written. */ - recurrencesByTax?: (/* An amount associated with a specific recurrence. */ RecurrenceAmountWithTax)[]; + _updated_at: string; }; } - export type TypeGetAg = "base_price" | "work_price"; - /** - * The availability rule error - */ - export interface ValidateAvailabilityFileError { - /** - * The line number where the error was found - */ - line?: number; - /** - * The error message - */ - msg: string; - /** - * Data related to the error - */ - data?: string; - } - /** - * The availability map file result payload - * example: - * { - * "status": "success", - * "rules_parsed_count": 10, - * "errors": [] - * } - */ - export interface ValidateAvailabilityFileResult { - /** - * The status of the validation - */ - status: "success" | "error"; - /** - * The number of rules successfully parsed - */ - rules_parsed_count: number; - /** - * The errors found on the file - */ - errors: /* The availability rule error */ ValidateAvailabilityFileError[]; - } /** - * A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a - * boolean `default` saying whether this is the entity's fallback. + * Whether a tree row's version is the one in effect at `as_of`, or one still ahead of it. * - * `default` is always present and always a boolean, so a client can branch on "did I get the - * fallback?" without knowing how one is stored. The reserved condition a fallback is actually - * pinned under never appears here. + * - `active`: the version with the latest `valid_from` at or before `as_of` + * - `scheduled`: the variant's first version, which is later than `as_of` * - * example: - * { - * "postal_code": "46045", - * "default": false - * } */ - export interface VariantConditions { - [name: string]: any; - default: boolean; - } + export type VariantTreeRowStatus = "active" | "scheduled"; /** - * The attribute values this version overrides on the base entity, keyed by attribute name. + * The values this version overrides on the base entity, keyed by entity field name. * - * Only attributes currently declaring `overridable_attribute` are applied. Metadata fields - * (anything underscore-prefixed), readonly attributes, hidden attributes and non-overridable - * attributes present here are ignored rather than rejected, so a client working from a slightly - * stale schema snapshot still succeeds instead of failing on fields it could not have known to - * drop. An attribute's `render_condition` says when to show it and has no bearing on whether a - * variant may override it. + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. * - * Ignored means *not updated*, never *removed*: a value already stored for an attribute that is - * not currently overridable is preserved, so removing and restoring the flag deactivates and - * then reactivates the same override. + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. * - * A composite price's `price_components` is an ordinary overridable relation attribute: a - * composite variant pins its component variants here the same way any other relation value is - * set, with no special handling. + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. * * example: * { @@ -10996,12 +17780,9 @@ declare namespace Components { [name: string]: any; } /** - * One version of one variant: the attribute overrides it carries, the instant it takes effect, - * and the variant it belongs to. - * - * These are the version's **own** overrides, not the base entity overlaid with them — this is - * what an editing screen loads and saves, and what it edits is the overrides. Composing them onto - * the entity is what `:resolve` answers. + * One version of one variant: the overrides it carries, the instant it takes effect, and the + * variant it belongs to. These are the version's own overrides; `:resolve` composes them onto + * the entity. * */ export interface VariantVersion { @@ -11015,16 +17796,10 @@ declare namespace Components { * price-sp26d1yo */ entity_id: string; - schema: /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - ConditionalEntitySlug; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; /** - * The situation the variant applies to, plus the boolean `default` discriminator. A property - * of the variant rather than of this version: every version of a variant carries the same - * one, and no version write can change it. + * The situation the variant applies to, plus the boolean `default` discriminator. A + * property of the variant: every version carries the same one. * * example: * { @@ -11037,30 +17812,27 @@ declare namespace Components { default: boolean; }; /** - * When this version takes effect, canonicalized to millisecond-precision UTC. A version's - * identity within its variant — it never moves. + * When this version takes effect, canonicalized to millisecond-precision UTC. Its identity + * within the variant. * * example: * 2027-01-01T00:00:00.000Z */ valid_from: string; values: /** - * The attribute values this version overrides on the base entity, keyed by attribute name. + * The values this version overrides on the base entity, keyed by entity field name. * - * Only attributes currently declaring `overridable_attribute` are applied. Metadata fields - * (anything underscore-prefixed), readonly attributes, hidden attributes and non-overridable - * attributes present here are ignored rather than rejected, so a client working from a slightly - * stale schema snapshot still succeeds instead of failing on fields it could not have known to - * drop. An attribute's `render_condition` says when to show it and has no bearing on whether a - * variant may override it. + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. * - * Ignored means *not updated*, never *removed*: a value already stored for an attribute that is - * not currently overridable is preserved, so removing and restoring the flag deactivates and - * then reactivates the same override. + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. * - * A composite price's `price_components` is an ordinary overridable relation attribute: a - * composite variant pins its component variants here the same way any other relation value is - * set, with no special handling. + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. * * example: * { @@ -11078,50 +17850,106 @@ declare namespace Components { */ _updated_at: string; /** - * The revision a write to this version must carry to be accepted. Always current: every read - * that returns one is strongly consistent, so it is never a marker a write would be refused - * for having read too early. - * + * The revision a write to this version must carry. Read from a strongly consistent read. * example: * 3 */ _revision: number; } - export interface VariantWriteWarning { + export interface VariantVersionList { /** - * - `VARIANT_COUNT_APPROACHING_CAP`: this entity is nearing the number of variants it may - * hold. Surfaced rather than rejected, so an importer finds out with a whole run's notice - * instead of discovering the limit halfway through a refresh. - * + * A page of the variant's timeline, in the requested `order`. */ - code: "VARIANT_COUNT_APPROACHING_CAP"; - message: string; - /** - * Variants this entity holds, including the one just created. + results: /** + * One version of one variant as a listing reports it: `VariantVersion` without `_revision`. + * Read the version through its own `GET` to get the revision a write must carry. + * */ - variant_count: number; + VariantVersionSnapshot[]; /** - * Variants this entity may hold. Configurable per organization. + * The cursor that continues this timeline, absent only on the last page — the only + * end-of-data signal, since a short or empty page can still carry one. Send it back as + * `cursor`, against the same variant and `order`. + * + * example: + * eyJzayI6IlYjcHJpY2Utc3AyNmQxeW8jdmFyLTQ2MDQ1IzIwMjYtMDEtMDFUMDA6MDA6MDAuMDAwWiIsIm9yZGVyIjoiYXNjIn0 */ - cap: number; + next?: string; } /** - * Something a version write moved. A version write is never refused for being late — backdating a - * version, and editing or deleting one that has already been superseded, are both accepted — so - * what a caller gets instead is a warning naming exactly what changed. One write can carry both - * codes. + * One version of one variant as a listing reports it: `VariantVersion` without `_revision`. + * Read the version through its own `GET` to get the revision a write must carry. * */ - export interface VersionWriteWarning { + export interface VariantVersionSnapshot { /** - * - `ACTIVE_VERSION_REPLACED`: what resolves **now** changed, other than by a newer version - * taking effect. The version in effect was written behind, or removed. - * - `SUPERSEDED_VERSION_WRITTEN`: what a past-dated (`as_of`) read returns changed. The write - * landed on, or created, a version that is not the one currently in effect. + * example: + * var-46045 + */ + variant_id: string; + /** + * example: + * price-sp26d1yo + */ + entity_id: string; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; + /** + * The situation the variant applies to, plus the boolean `default` discriminator. A + * property of the variant: every version carries the same one. * + * example: + * { + * "postal_code": "46045", + * "default": false + * } */ - code: "ACTIVE_VERSION_REPLACED" | "SUPERSEDED_VERSION_WRITTEN"; - message: string; + conditions: { + [name: string]: any; + default: boolean; + }; + /** + * When this version takes effect, canonicalized to millisecond-precision UTC. Its identity + * within the variant. + * + * example: + * 2027-01-01T00:00:00.000Z + */ + valid_from: string; + values: /** + * The values this version overrides on the base entity, keyed by entity field name. + * + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. + * + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. + * + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. + * + * example: + * { + * "unit_amount": 2499, + * "unit_amount_decimal": "24.99" + * } + */ + VariantValues; + /** + * When this version was created. + */ + _created_at: string; + /** + * When this version was last written. + */ + _updated_at: string; + } + /** + * Which version a write moved, and which one was in effect while it did. + */ + export interface VersionMoved { /** * The version this write created, changed or removed. * example: @@ -11130,7 +17958,7 @@ declare namespace Components { valid_from: string; /** * The version in effect when the write landed, before it did. Absent when the variant had - * none — every version of it still scheduled. + * none. Advisory, and may lag the timeline by milliseconds. * * example: * 2026-01-01T00:00:00.000Z @@ -11138,9 +17966,59 @@ declare namespace Components { active_valid_from?: string; } /** - * A version as a write left it, together with anything the write moved. + * Something worth knowing that did not stop a write. One vocabulary for every write; `details` + * is typed per `code`, and a write raises each code at most once. + * + */ + export type WriteWarning = /** + * Something worth knowing that did not stop a write. One vocabulary for every write; `details` + * is typed per `code`, and a write raises each code at most once. * */ + { + code: "VARIANT_COUNT_APPROACHING_CAP"; + message: string; + details: { + /** + * Variants this entity holds, including the one just written. + */ + variant_count: number; + /** + * Variants this entity may hold. Configurable per deploy. + */ + cap: number; + }; + } | { + code: "ACTIVE_VERSION_CHANGED"; + message: string; + details: /* Which version a write moved, and which one was in effect while it did. */ VersionMoved; + } | { + code: "SUPERSEDED_VERSION_WRITTEN"; + message: string; + details: /* Which version a write moved, and which one was in effect while it did. */ VersionMoved; + } | { + code: "ATTRIBUTES_NOT_APPLIED"; + message: string; + details: { + attributes: [ + /** + * One override that did not apply, and why — reported by a write for the attributes in its + * body, and by a resolved payload for the stored overrides composition passed over. + * + */ + InertOverride, + .../** + * One override that did not apply, and why — reported by a write for the attributes in its + * body, and by a resolved payload for the stored overrides composition passed over. + * + */ + InertOverride[] + ]; + }; + }; + /** + * A version as a write left it, together with anything the write moved. + */ export interface WrittenVariantVersion { /** * example: @@ -11152,16 +18030,10 @@ declare namespace Components { * price-sp26d1yo */ entity_id: string; - schema: /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - ConditionalEntitySlug; + schema: /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ ConditionalEntitySlug; /** - * The situation the variant applies to, plus the boolean `default` discriminator. A property - * of the variant rather than of this version: every version of a variant carries the same - * one, and no version write can change it. + * The situation the variant applies to, plus the boolean `default` discriminator. A + * property of the variant: every version carries the same one. * * example: * { @@ -11174,30 +18046,27 @@ declare namespace Components { default: boolean; }; /** - * When this version takes effect, canonicalized to millisecond-precision UTC. A version's - * identity within its variant — it never moves. + * When this version takes effect, canonicalized to millisecond-precision UTC. Its identity + * within the variant. * * example: * 2027-01-01T00:00:00.000Z */ valid_from: string; values: /** - * The attribute values this version overrides on the base entity, keyed by attribute name. + * The values this version overrides on the base entity, keyed by entity field name. * - * Only attributes currently declaring `overridable_attribute` are applied. Metadata fields - * (anything underscore-prefixed), readonly attributes, hidden attributes and non-overridable - * attributes present here are ignored rather than rejected, so a client working from a slightly - * stale schema snapshot still succeeds instead of failing on fields it could not have known to - * drop. An attribute's `render_condition` says when to show it and has no bearing on whether a - * variant may override it. + * A field is overridable if its attribute declares `overridable_attribute` — which readonly, + * hidden, computed and metadata fields, and types no variant may override, cannot be given — + * or if a capability declaring `overridable_attribute` names it in `managed_fields`, which + * excludes only readonly and metadata fields. * - * Ignored means *not updated*, never *removed*: a value already stored for an attribute that is - * not currently overridable is preserved, so removing and restoring the flag deactivates and - * then reactivates the same override. + * Fields that are not overridable are reported in the write's `warnings` rather than rejected, + * and keep whatever value they already had. An append seeds them from the version in effect at + * its own `valid_from`. * - * A composite price's `price_components` is an ordinary overridable relation attribute: a - * composite variant pins its component variants here the same way any other relation value is - * set, with no special handling. + * A composite price's `price_components` is an ordinary overridable relation attribute, + * referencing component entities rather than variants or versions. * * example: * { @@ -11215,27 +18084,22 @@ declare namespace Components { */ _updated_at: string; /** - * The revision a write to this version must carry to be accepted. Always current: every read - * that returns one is strongly consistent, so it is never a marker a write would be refused - * for having read too early. - * + * The revision a write to this version must carry. Read from a strongly consistent read. * example: * 3 */ _revision: number; /** - * What this write moved, if anything. Empty in the ordinary case — a client reads its - * length rather than branching on its absence. + * What this write moved, and anything in the body it did not store. Always present, + * and empty in the ordinary case. * */ warnings: /** - * Something a version write moved. A version write is never refused for being late — backdating a - * version, and editing or deleting one that has already been superseded, are both accepted — so - * what a caller gets instead is a warning naming exactly what changed. One write can carry both - * codes. + * Something worth knowing that did not stop a write. One vocabulary for every write; `details` + * is typed per `code`, and a write raises each code at most once. * */ - VersionWriteWarning[]; + WriteWarning[]; } } } @@ -11243,12 +18107,7 @@ declare namespace Paths { namespace $AppendConditionalVariantVersion { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type VariantId = string; } export interface PathParameters { @@ -11258,35 +18117,35 @@ declare namespace Paths { } export type RequestBody = Components.Schemas.AppendVersionRequest; namespace Responses { - export type $201 = /** - * A version as a write left it, together with anything the write moved. - * - */ - Components.Schemas.WrittenVariantVersion; + export type $201 = /* A version as a write left it, together with anything the write moved. */ Components.Schemas.WrittenVariantVersion; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -11341,6 +18200,72 @@ declare namespace Paths { export type $404 = Components.Schemas.Error; } } + namespace $BatchDeleteConditionalVariants { + namespace Parameters { + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; + } + export interface PathParameters { + slug: Parameters.Slug; + } + export type RequestBody = /* A batch of variant and version deletes under one schema, each item naming the entity it removes from. */ Components.Schemas.BatchDeleteVariantsRequest; + namespace Responses { + export type $200 = /* What a batch delete did: one entry per item, in request order, and a count per outcome. */ Components.Schemas.BatchDeleteResult; + export type $400 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; + export type $404 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + } + } + namespace $BatchUpsertConditionalVariants { + namespace Parameters { + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; + } + export interface PathParameters { + slug: Parameters.Slug; + } + export type RequestBody = /* A batch of variant writes under one schema, each item naming the entity it writes to. */ Components.Schemas.BatchUpsertVariantsRequest; + namespace Responses { + export type $200 = /* What a batch upsert did: one entry per item, in request order, and a count per outcome. */ Components.Schemas.BatchUpsertResult; + export type $400 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; + export type $404 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + } + } namespace $CalculatePricingDetails { export interface RequestBody { line_items?: /* A valid set of product prices, quantities, (discounts) and taxes from a client. */ Components.Schemas.PriceItemsDto; @@ -11385,12 +18310,7 @@ declare namespace Paths { namespace $CreateConditionalVariant { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; } export interface PathParameters { slug: Parameters.Slug; @@ -11400,29 +18320,33 @@ declare namespace Paths { namespace Responses { export type $201 = Components.Schemas.CreatedVariant; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -11431,12 +18355,7 @@ declare namespace Paths { namespace $DeleteConditionalVariant { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type VariantId = string; } export interface PathParameters { @@ -11447,29 +18366,33 @@ declare namespace Paths { namespace Responses { export type $200 = Components.Schemas.DeletedVariant; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -11479,12 +18402,7 @@ declare namespace Paths { namespace Parameters { export type EntityId = string; export type Revision = number; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type ValidFrom = string; export type VariantId = string; } @@ -11500,29 +18418,33 @@ declare namespace Paths { namespace Responses { export type $200 = Components.Schemas.DeletedVariantVersion; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -11544,12 +18466,7 @@ declare namespace Paths { namespace $GetActiveConditionalVariantVersion { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type VariantId = string; } export interface PathParameters { @@ -11559,61 +18476,111 @@ declare namespace Paths { } namespace Responses { export type $200 = /** - * One version of one variant: the attribute overrides it carries, the instant it takes effect, - * and the variant it belongs to. - * - * These are the version's **own** overrides, not the base entity overlaid with them — this is - * what an editing screen loads and saves, and what it edits is the overrides. Composing them onto - * the entity is what `:resolve` answers. + * One version of one variant: the overrides it carries, the instant it takes effect, and the + * variant it belongs to. These are the version's own overrides; `:resolve` composes them onto + * the entity. * */ Components.Schemas.VariantVersion; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; + export type $404 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $409 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + } + } + namespace $GetConditionSets { + namespace Parameters { + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; + } + export interface PathParameters { + slug: Parameters.Slug; + } + namespace Responses { + export type $200 = Components.Schemas.ConditionSetCatalog; + export type $400 = Components.Schemas.Error; + } + } + namespace $GetConditionalVariantTree { + namespace Parameters { + export type EntityId = string; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; + } + export interface PathParameters { + slug: Parameters.Slug; + entity_id: Parameters.EntityId; + } + export type RequestBody = /** + * The variants list's request plus `as_of`, the instant each row's version is selected at. + * `size` is clamped at 100 here; every other property means what it means on the list. + * + */ + Components.Schemas.VariantTreeRequest; + namespace Responses { + export type $200 = Components.Schemas.VariantTree; + export type $400 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; - } - } - namespace $GetConditionSets { - namespace Parameters { - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. + export type $409 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ - Components.Schemas.ConditionalEntitySlug; - } - export interface PathParameters { - slug: Parameters.Slug; - } - namespace Responses { - export type $200 = Components.Schemas.ConditionSetCatalog; - export type $400 = Components.Schemas.Error; + Components.Schemas.ConditionalPricingError; } } namespace $GetConditionalVariantVersion { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type ValidFrom = string; export type VariantId = string; } @@ -11625,30 +18592,40 @@ declare namespace Paths { } namespace Responses { export type $200 = /** - * One version of one variant: the attribute overrides it carries, the instant it takes effect, - * and the variant it belongs to. - * - * These are the version's **own** overrides, not the base entity overlaid with them — this is - * what an editing screen loads and saves, and what it edits is the overrides. Composing them onto - * the entity is what `:resolve` answers. + * One version of one variant: the overrides it carries, the instant it takes effect, and the + * variant it belongs to. These are the version's own overrides; `:resolve` composes them onto + * the entity. * */ Components.Schemas.VariantVersion; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $409 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -11800,15 +18777,13 @@ declare namespace Paths { export type $404 = Components.Schemas.Error; } } - namespace $PatchActiveConditionalVariantVersion { + namespace $ListConditionalVariantVersions { namespace Parameters { + export type Cursor = string; export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Limit = number; + export type Order = "asc" | "desc"; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type VariantId = string; } export interface PathParameters { @@ -11816,51 +18791,148 @@ declare namespace Paths { entity_id: Parameters.EntityId; variant_id: Parameters.VariantId; } - export type RequestBody = Components.Schemas.PatchVersionRequest; + export interface QueryParameters { + limit?: Parameters.Limit; + order?: Parameters.Order; + cursor?: Parameters.Cursor; + } namespace Responses { - export type $200 = /** - * A version as a write left it, together with anything the write moved. + export type $200 = Components.Schemas.VariantVersionList; + export type $400 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; + export type $404 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $409 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ - Components.Schemas.WrittenVariantVersion; + Components.Schemas.ConditionalPricingError; + } + } + namespace $ListConditionalVariants { + namespace Parameters { + export type EntityId = string; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; + } + export interface PathParameters { + slug: Parameters.Slug; + entity_id: Parameters.EntityId; + } + export type RequestBody = /** + * How to narrow and page a variant listing. Every property is optional, so `{}` asks for the + * first ten variants in `variant_id` order, but the body itself is required. `conditions` and + * `search` narrow independently and a variant must satisfy both. + * + */ + Components.Schemas.ListVariantsRequest; + namespace Responses { + export type $200 = Components.Schemas.VariantList; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; } } - namespace $PatchConditionalVariantVersion { + namespace $PatchActiveConditionalVariantVersion { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; + export type VariantId = string; + } + export interface PathParameters { + slug: Parameters.Slug; + entity_id: Parameters.EntityId; + variant_id: Parameters.VariantId; + } + export type RequestBody = Components.Schemas.PatchVersionRequest; + namespace Responses { + export type $200 = /* A version as a write left it, together with anything the write moved. */ Components.Schemas.WrittenVariantVersion; + export type $400 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; + export type $404 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. + * + */ + Components.Schemas.ConditionalPricingError; + export type $409 = /** + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ - Components.Schemas.ConditionalEntitySlug; + Components.Schemas.ConditionalPricingError; + } + } + namespace $PatchConditionalVariantVersion { + namespace Parameters { + export type EntityId = string; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type ValidFrom = string; export type VariantId = string; } @@ -11872,35 +18944,35 @@ declare namespace Paths { } export type RequestBody = Components.Schemas.PatchVersionRequest; namespace Responses { - export type $200 = /** - * A version as a write left it, together with anything the write moved. - * - */ - Components.Schemas.WrittenVariantVersion; + export type $200 = /* A version as a write left it, together with anything the write moved. */ Components.Schemas.WrittenVariantVersion; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -11956,12 +19028,7 @@ declare namespace Paths { namespace $ReplaceActiveConditionalVariantVersion { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type VariantId = string; } export interface PathParameters { @@ -11971,35 +19038,35 @@ declare namespace Paths { } export type RequestBody = Components.Schemas.ReplaceVersionRequest; namespace Responses { - export type $200 = /** - * A version as a write left it, together with anything the write moved. - * - */ - Components.Schemas.WrittenVariantVersion; + export type $200 = /* A version as a write left it, together with anything the write moved. */ Components.Schemas.WrittenVariantVersion; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -12008,12 +19075,7 @@ declare namespace Paths { namespace $ReplaceConditionalVariantVersion { namespace Parameters { export type EntityId = string; - export type Slug = /** - * Schema slug of an entity type that can be conditional — the `{slug}` of every - * conditional-pricing route. - * - */ - Components.Schemas.ConditionalEntitySlug; + export type Slug = /* Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route. */ Components.Schemas.ConditionalEntitySlug; export type ValidFrom = string; export type VariantId = string; } @@ -12025,68 +19087,77 @@ declare namespace Paths { } export type RequestBody = Components.Schemas.ReplaceVersionRequest; namespace Responses { - export type $200 = /** - * A version as a write left it, together with anything the write moved. - * - */ - Components.Schemas.WrittenVariantVersion; + export type $200 = /* A version as a write left it, together with anything the write moved. */ Components.Schemas.WrittenVariantVersion; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; + export type $403 = Components.Schemas.Error; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; } } namespace $ResolveConditionalEntity { - export type RequestBody = Components.Schemas.ResolveConditionalEntityRequest; + export type RequestBody = /** + * A resolve names one conditional entity and selects its variants either by `context` or by + * `variant_id`, never both. `context: {}` matches nothing and so returns the `default` + * variant, which is how to ask for it without knowing its id. + * + */ + Components.Schemas.ResolveConditionalEntityRequest; namespace Responses { export type $200 = Components.Schemas.ResolvedVariants; export type $400 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $404 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; export type $409 = /** - * An error from a conditional-pricing operation, carrying a machine-readable `code` - * from the conditional-pricing vocabulary plus any structured data about the failure, - * so a client can branch on the kind of failure rather than parse the message. - * Referenced only by the operations that emit these codes; every other operation - * keeps the plain `Error` shape. + * An error from a conditional-pricing operation, carrying a `code` plus the structured data + * that code explains. `details` is typed per code: narrow on `code` and the object under it + * declares exactly the fields that code sends. + * + * A request these schemas reject is answered by the request validator with a message and + * carries neither `code` nor `details` — the last member of the union. * */ Components.Schemas.ConditionalPricingError; @@ -13639,17 +20710,7 @@ export interface OperationMethods { /** * $getConditionSets - $getConditionSets * - * Returns the condition sets built in for one conditional entity type: the situations a - * conditional Product, Price or Coupon is commonly varied by, ready to be copied into that - * schema's `conditions` array and extended or modified from there. - * - * Which sets exist depends on the schema — an offer window is a Product's dimension, a delivery - * area is a Price's and a Coupon's — so only the sets built in for `slug` are returned. - * - * Static, read-only reference data. The catalog is the same for every organization and is not - * applied to any schema by this endpoint — adding conditions to a schema stays an Entity API - * write. - * + * Returns the condition sets built in for one conditional entity type, ready to copy into that schema's `conditions` array. Read-only, and the same for every organization. */ '$getConditionSets'( parameters?: Parameters | null, @@ -13659,24 +20720,15 @@ export interface OperationMethods { /** * $resolveConditionalEntity - $resolveConditionalEntity * - * Resolves which of a conditional entity's variants apply to a situation, and returns each one - * composed: the base entity overlaid with the values of the version in effect at `as_of`. - * - * Resolution is two selections in a fixed order — the variant, by matching `context` against - * the conditions each variant pins; then the version, by `as_of`. It is always scoped to one - * logical entity, so it stays a cheap, predictable lookup rather than an open search. - * - * Matching follows two rules worth knowing before assembling a context. A condition a variant - * does **not** pin matches any value, which is what lets a condition be added to a schema - * without breaking the variants that already exist. A condition **missing from `context`**, - * however, does not satisfy one a variant pinned: an incomplete integration resolves to - * nothing rather than silently matching another segment's variants. + * Returns the variants of one conditional entity that apply, each composed: the base entity + * overlaid with the version in effect at `as_of`. * - * When nothing matches, the entity's `default` variant is returned if it has one. There is no - * implicit fallback to the unmodified base entity — its values are the ones no variant - * overrode, which is not an answer to "what applies here". + * Select the variant either by `context`, matched against the conditions each variant pins, or + * by `variant_id`. Exactly one of the two. A condition a variant leaves unpinned matches any + * value; a condition absent from `context` matches only variants that leave it unpinned. * - * Availability is a separate mechanism and is never consulted here. + * When no variant matches, the entity's `default` variant is returned, or `results` is empty. + * `options.hydrate` replaces relation references with the entities they reference. * */ '$resolveConditionalEntity'( @@ -13687,37 +20739,14 @@ export interface OperationMethods { /** * $createConditionalVariant - $createConditionalVariant * - * Creates one variant of a conditional entity, together with the first version carrying its - * values. Never two calls: a variant that existed without a version would be an entity holding - * a condition tuple it cannot answer with. + * Creates one variant together with its first version. * - * The body pins the situation the variant applies to. Pins are exact values only — predicates - * are a read-side concept and are rejected here — and are stored canonicalized for their - * condition's type, so two spellings of one instant, or one town written two ways, are one - * variant rather than two that no context can tell apart. + * `conditions` pins the situation the variant applies to, as exact values. A variant must pin + * at least one condition or be marked `default`, of which an entity may have one, and its + * condition values are fixed once created. * - * Three write rules are worth knowing before the first call: - * - * - A variant must pin at least one condition or be marked `default`. A variant pinning nothing - * would be a universal wildcard matching every resolve, which is a far more dangerous thing - * than a fallback and far easier to create by accident. - * - `default` is a property of the variant, set by the `default` flag, and is never a value in - * `conditions` — not even `false`. A `default` variant cannot pin anything else, and an entity - * can have only one, enforced by the ordinary condition-tuple guard rather than by a rule of - * its own. Any entity may have one; nothing is declared in the schema to allow it. - * - Condition values are immutable afterwards. A variant's identity is the situation it applies - * to, and orders and contracts pin it. **A condition added to a schema that already has - * variants is effectively one-way**: every existing variant is a wildcard on the new - * dimension, but the first variant that pins it is ambiguous against all of them, and - * retro-pinning the others is blocked by this same rule. - * - * Attribute values are applied only for attributes currently carrying `overridable_attribute`. - * Metadata and non-overridable fields present in the body are ignored rather than rejected, so a - * client working from a slightly stale schema snapshot still succeeds. - * - * `variant_id` is always server-generated and returned, and is not accepted in the body — the - * request schema admits no such property. It is the durable key orders and contracts pin, so it - * cannot be something two independent importers could collide on. + * Values are stored only for attributes carrying `overridable_attribute`; the rest are + * reported in `warnings` rather than rejected. `variant_id` is server-generated. * */ '$createConditionalVariant'( @@ -13726,20 +20755,46 @@ export interface OperationMethods { config?: AxiosRequestConfig ): OperationResponse /** - * $getActiveConditionalVariantVersion - $getActiveConditionalVariantVersion + * $listConditionalVariants - $listConditionalVariants + * + * Lists a conditional entity's variants and the conditions each one pins. A `POST` because the + * condition filter is a structured object; nothing is written. The body is required, so send + * `{}` for the first page. + * + * `conditions` filters on the pins, taking the same predicates a resolve context does, and + * matches a variant only where it pins that condition. `search` is free text over pinned + * values; `sort` orders by one pin. + * + * Offset paging up to the search index's window, then the `cursor` from `next`. + * + */ + '$listConditionalVariants'( + parameters?: Parameters | null, + data?: Paths.$ListConditionalVariants.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + /** + * $getConditionalVariantTree - $getConditionalVariantTree + * + * The variants list, each row carrying the version in effect at `as_of` and a `status` saying + * whether that version is `active` or still `scheduled`. * - * Returns the version of this variant that is currently in effect — the one with the latest - * `valid_from` at or before now. + * Takes everything the variants list takes, plus `as_of`. `size` is clamped at 100, and a + * variant mid-delete is omitted from `results`. * - * The "open this variant" read: no date arithmetic is asked of the caller, and what comes back - * carries the `_revision` a write to that version has to be sent with, so an editing screen can - * load and save without working out which version it is looking at. + */ + '$getConditionalVariantTree'( + parameters?: Parameters | null, + data?: Paths.$GetConditionalVariantTree.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + /** + * $getActiveConditionalVariantVersion - $getActiveConditionalVariantVersion * - * What is returned is the version's own attribute overrides, not the base entity overlaid with - * them. Composing the two is what `:resolve` answers. + * Returns the version of this variant in effect now — the latest `valid_from` at or before now + * — with the `_revision` a write to it must carry. * - * A variant staged ahead of its launch has versions but none of them in effect, and is reported - * as having none rather than as not existing — the two are fixed differently. + * These are the version's own overrides; `:resolve` composes them onto the entity. * */ '$getActiveConditionalVariantVersion'( @@ -13750,20 +20805,11 @@ export interface OperationMethods { /** * $replaceActiveConditionalVariantVersion - $replaceActiveConditionalVariantVersion * - * Replaces the values of the version currently in effect, wholesale. + * Replaces the values of the version in effect. The body is the complete set of overrides: an + * overridable attribute absent from it stops being overridden, and one the variant may not + * override keeps its stored value. * - * The body is the complete set of attribute overrides: an attribute the variant may override and - * that is absent from it stops being overridden. Attributes the variant may **not** override are - * ignored where the body carries them, and their stored value is kept rather than dropped — a - * routine full-snapshot write must not erase an override the moment its attribute's flag happens - * to be off. - * - * Editing the version in effect is the ordinary way a live price is corrected, and warns about - * nothing: what changes is what that version *says*, not which version is in effect. - * - * Neither `valid_from` nor `conditions` can be changed here. Both are accepted when they match - * what is stored, so a client building its body from the version it loaded need not strip them - * out first, and both are refused when they name something else. + * `valid_from` and `conditions` are accepted only unchanged. * */ '$replaceActiveConditionalVariantVersion'( @@ -13774,15 +20820,8 @@ export interface OperationMethods { /** * $patchActiveConditionalVariantVersion - $patchActiveConditionalVariantVersion * - * Changes only the fields it names on the version currently in effect. - * - * Everything the body does not mention is left as stored — the "just nudge this number" write. A - * `null` is a value like any other rather than a deletion; a client that wants an attribute to - * stop being overridden sends the complete snapshot without it through `PUT`. - * - * Attempting to change a pinned condition value is refused here in particular: a partial update - * is the path a caller reaches for by accident, and a variant's conditions are the situation it - * applies to, which the orders and contracts pinning it depend on not shifting. + * Changes only the fields it names on the version in effect. `null` sets a value rather than + * removing an override; use the replace operation to remove one. * */ '$patchActiveConditionalVariantVersion'( @@ -13793,23 +20832,11 @@ export interface OperationMethods { /** * $deleteConditionalVariant - $deleteConditionalVariant * - * Removes one variant of a conditional entity: the condition tuple it holds, its registration - * in the search index, and every version it accumulated. + * Removes one variant: its condition tuple, its index entry and all its versions. The tuple + * becomes reusable, and an interrupted delete is safe to send again. * - * Two phases. The first frees the tuple and deregisters the variant, and is what makes the - * combination of condition values immediately reusable — the second removes the version rows in - * batches afterwards. A response arrives only once both have finished for this request, but the - * tuple is reusable from the moment the first completes, whether or not the second did: a - * variant with more versions than one transaction can carry is the ordinary case, not an edge - * one. An interrupted delete is safe to send again; it picks up where it stopped. - * - * Nothing is archived. A variant an order or contract pins stops resolving, and hydration drops - * the reference leniently rather than failing the read. - * - * This removes the **variant**, not one of its versions. To remove a single version, name it on - * `…/variants/{variant_id}/versions/{valid_from}` — including the one currently in effect, which - * deliberately has no "delete whichever is live" shorthand: that is exactly the write nobody - * should be able to ask for without saying which version they meant. + * Orders and contracts pinning the variant stop resolving. To remove a single version, address + * it under `versions/{valid_from}`. * */ '$deleteConditionalVariant'( @@ -13818,27 +20845,26 @@ export interface OperationMethods { config?: AxiosRequestConfig ): OperationResponse /** - * $appendConditionalVariantVersion - $appendConditionalVariantVersion - * - * Appends a version to a variant: a new set of values taking effect at its own instant. + * $listConditionalVariantVersions - $listConditionalVariantVersions * - * This is how a price changes. No version carries an end date and nothing is superseded - * explicitly — the version in effect at an instant is simply the one with the latest `valid_from` - * at or before it, so appending a later version is the whole of "this is the new price from then - * on". A version dated in the future is staged and excluded from resolution until its date. + * Lists one variant's versions. Cursor paging only: a page may be short or empty and still + * carry a `next`, so page until `next` is absent. A cursor is bound to one variant and one + * `order`. * - * **A version is never refused for being late.** A `valid_from` in the past is written like any - * other and answered with warnings in `warnings` naming what it moved — what resolves now, what a - * past-dated read returns, or both. Correcting a price that took effect last week is ordinary - * work; the alternative, deleting and recreating the variant, breaks every order and contract - * pinning its id. + */ + '$listConditionalVariantVersions'( + parameters?: Parameters | null, + data?: any, + config?: AxiosRequestConfig + ): OperationResponse + /** + * $appendConditionalVariantVersion - $appendConditionalVariantVersion * - * What is refused is appending at a `valid_from` the variant already has: that write means either - * "replace it" or "and also this", and only the caller knows which. The two operations both - * exist, on the dated version path. + * Appends a version taking effect at its own instant. The version in effect at any instant is + * the one with the latest `valid_from` at or before it; a future one is staged until its date. * - * The variant's `conditions` are its identity and are fixed at creation; they may be sent back - * unchanged but never changed. + * A past `valid_from` is accepted and reported in `warnings`. One the variant already has is + * refused — replace or patch that version instead. * */ '$appendConditionalVariantVersion'( @@ -13849,12 +20875,7 @@ export interface OperationMethods { /** * $getConditionalVariantVersion - $getConditionalVariantVersion * - * Returns one specific version of a variant, by the instant it takes effect — what a form editing - * that version loads. - * - * Exact, never nearest: an instant the variant has no version at is a not-found rather than the - * version that would be in effect at it. That question is the shorthand read's, or `:resolve`'s. - * + * Returns one version by the instant it takes effect. Exact, never nearest. */ '$getConditionalVariantVersion'( parameters?: Parameters | null, @@ -13864,16 +20885,8 @@ export interface OperationMethods { /** * $replaceConditionalVariantVersion - $replaceConditionalVariantVersion * - * Replaces one version's values wholesale, addressed by its `valid_from`. - * - * Editable whatever its date, at both ends of the timeline: a scheduled version must stay - * editable so a staged price can be corrected before it goes live rather than accumulating dead - * versions beside it, and a past one must stay editable because correcting history is ordinary - * work. Writing a superseded version is answered with a warning naming what a past-dated read now - * returns; it is not refused. - * - * Attributes the variant may not override are ignored where the body carries them, and their - * stored value is preserved rather than dropped. + * Replaces one version's values, whatever its date. Attributes the variant may not override + * keep their stored value. Writing a superseded version is reported in `warnings`. * */ '$replaceConditionalVariantVersion'( @@ -13884,12 +20897,7 @@ export interface OperationMethods { /** * $patchConditionalVariantVersion - $patchConditionalVariantVersion * - * Changes only the fields it names on one version, addressed by its `valid_from`. - * - * Everything the body does not mention is left as stored. A partial update that tries to change a - * pinned condition value is refused: condition values are immutable after a variant is created, - * and this is the path that rule is most likely to be broken on by accident. - * + * Changes only the fields it names on one version. */ '$patchConditionalVariantVersion'( parameters?: Parameters | null, @@ -13899,18 +20907,8 @@ export interface OperationMethods { /** * $deleteConditionalVariantVersion - $deleteConditionalVariantVersion * - * Removes one version of a variant. - * - * Withdrawing a scheduled adjustment is what this is for, and deleting a future version warns - * about nothing — nothing that has resolved, or could have resolved, changes. Deleting a version - * that has taken effect is allowed too and answered with a warning: it changes what a past-dated - * read returns, and if it was the version in effect it changes what resolves now. - * - * **A variant's last remaining version cannot be deleted.** Such a variant would still hold its - * condition tuple and still be selectable, and then resolve to nothing — which is a variant delete - * wearing a version delete's clothes. Delete the variant instead; that frees the tuple too. - * - * The variant itself is untouched: it keeps its conditions, its tuple and its place in the index. + * Removes one version. What the removal moves is reported in `warnings`. A variant's last + * remaining version cannot be removed — delete the variant instead. * */ '$deleteConditionalVariantVersion'( @@ -13918,6 +20916,47 @@ export interface OperationMethods { data?: any, config?: AxiosRequestConfig ): OperationResponse + /** + * $batchUpsertConditionalVariants - $batchUpsertConditionalVariants + * + * Writes up to 100 variants or versions in one call. Each item names its own entity, so one + * call can span a tariff hierarchy, and addresses a variant by condition tuple rather than by + * id — the id it created or found is on the result entry. + * + * Each item's outcome is derived from what is stored: an unknown tuple is `variant_created`, a + * known tuple with no version at the item's `valid_from` is `version_created`, an existing + * version there is `updated`, and a write matching what is stored is `skipped`. An item + * without `valid_from` is a last-write-wins write with no `skipped` detection. + * + * Items addressing the same `(entity_id, conditions)` apply in array order; the rest run in + * parallel. No cross-item rollback, and no `_revision` guard. + * + */ + '$batchUpsertConditionalVariants'( + parameters?: Parameters | null, + data?: Paths.$BatchUpsertConditionalVariants.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + /** + * $batchDeleteConditionalVariants - $batchDeleteConditionalVariants + * + * Removes up to 100 variants or versions in one call. An item carrying `valid_from` removes + * that version; one without it removes the whole variant. + * + * Each item addresses its variant by `variant_id` beside its `entity_id`, or by the condition + * tuple it pins, never both. Use ids once a condition has left the schema, since its tuple can + * no longer be canonicalized. + * + * Items addressing the same variant apply in array order, resolved to ids first; the rest run + * in parallel. An item addressing a missing variant or version is `skipped`, and the call is + * safe to send again. + * + */ + '$batchDeleteConditionalVariants'( + parameters?: Parameters | null, + data?: Paths.$BatchDeleteConditionalVariants.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse } export interface PathsDictionary { @@ -14200,17 +21239,7 @@ export interface PathsDictionary { /** * $getConditionSets - $getConditionSets * - * Returns the condition sets built in for one conditional entity type: the situations a - * conditional Product, Price or Coupon is commonly varied by, ready to be copied into that - * schema's `conditions` array and extended or modified from there. - * - * Which sets exist depends on the schema — an offer window is a Product's dimension, a delivery - * area is a Price's and a Coupon's — so only the sets built in for `slug` are returned. - * - * Static, read-only reference data. The catalog is the same for every organization and is not - * applied to any schema by this endpoint — adding conditions to a schema stays an Entity API - * write. - * + * Returns the condition sets built in for one conditional entity type, ready to copy into that schema's `conditions` array. Read-only, and the same for every organization. */ 'get'( parameters?: Parameters | null, @@ -14222,24 +21251,15 @@ export interface PathsDictionary { /** * $resolveConditionalEntity - $resolveConditionalEntity * - * Resolves which of a conditional entity's variants apply to a situation, and returns each one - * composed: the base entity overlaid with the values of the version in effect at `as_of`. - * - * Resolution is two selections in a fixed order — the variant, by matching `context` against - * the conditions each variant pins; then the version, by `as_of`. It is always scoped to one - * logical entity, so it stays a cheap, predictable lookup rather than an open search. + * Returns the variants of one conditional entity that apply, each composed: the base entity + * overlaid with the version in effect at `as_of`. * - * Matching follows two rules worth knowing before assembling a context. A condition a variant - * does **not** pin matches any value, which is what lets a condition be added to a schema - * without breaking the variants that already exist. A condition **missing from `context`**, - * however, does not satisfy one a variant pinned: an incomplete integration resolves to - * nothing rather than silently matching another segment's variants. + * Select the variant either by `context`, matched against the conditions each variant pins, or + * by `variant_id`. Exactly one of the two. A condition a variant leaves unpinned matches any + * value; a condition absent from `context` matches only variants that leave it unpinned. * - * When nothing matches, the entity's `default` variant is returned if it has one. There is no - * implicit fallback to the unmodified base entity — its values are the ones no variant - * overrode, which is not an answer to "what applies here". - * - * Availability is a separate mechanism and is never consulted here. + * When no variant matches, the entity's `default` variant is returned, or `results` is empty. + * `options.hydrate` replaces relation references with the entities they reference. * */ 'post'( @@ -14252,37 +21272,14 @@ export interface PathsDictionary { /** * $createConditionalVariant - $createConditionalVariant * - * Creates one variant of a conditional entity, together with the first version carrying its - * values. Never two calls: a variant that existed without a version would be an entity holding - * a condition tuple it cannot answer with. - * - * The body pins the situation the variant applies to. Pins are exact values only — predicates - * are a read-side concept and are rejected here — and are stored canonicalized for their - * condition's type, so two spellings of one instant, or one town written two ways, are one - * variant rather than two that no context can tell apart. - * - * Three write rules are worth knowing before the first call: - * - * - A variant must pin at least one condition or be marked `default`. A variant pinning nothing - * would be a universal wildcard matching every resolve, which is a far more dangerous thing - * than a fallback and far easier to create by accident. - * - `default` is a property of the variant, set by the `default` flag, and is never a value in - * `conditions` — not even `false`. A `default` variant cannot pin anything else, and an entity - * can have only one, enforced by the ordinary condition-tuple guard rather than by a rule of - * its own. Any entity may have one; nothing is declared in the schema to allow it. - * - Condition values are immutable afterwards. A variant's identity is the situation it applies - * to, and orders and contracts pin it. **A condition added to a schema that already has - * variants is effectively one-way**: every existing variant is a wildcard on the new - * dimension, but the first variant that pins it is ambiguous against all of them, and - * retro-pinning the others is blocked by this same rule. + * Creates one variant together with its first version. * - * Attribute values are applied only for attributes currently carrying `overridable_attribute`. - * Metadata and non-overridable fields present in the body are ignored rather than rejected, so a - * client working from a slightly stale schema snapshot still succeeds. + * `conditions` pins the situation the variant applies to, as exact values. A variant must pin + * at least one condition or be marked `default`, of which an entity may have one, and its + * condition values are fixed once created. * - * `variant_id` is always server-generated and returned, and is not accepted in the body — the - * request schema admits no such property. It is the durable key orders and contracts pin, so it - * cannot be something two independent importers could collide on. + * Values are stored only for attributes carrying `overridable_attribute`; the rest are + * reported in `warnings` rather than rejected. `variant_id` is server-generated. * */ 'post'( @@ -14291,22 +21288,52 @@ export interface PathsDictionary { config?: AxiosRequestConfig ): OperationResponse } - ['/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}']: { + ['/v1/conditional-pricing/{slug}/entities/{entity_id}/variants:list']: { /** - * $getActiveConditionalVariantVersion - $getActiveConditionalVariantVersion + * $listConditionalVariants - $listConditionalVariants + * + * Lists a conditional entity's variants and the conditions each one pins. A `POST` because the + * condition filter is a structured object; nothing is written. The body is required, so send + * `{}` for the first page. + * + * `conditions` filters on the pins, taking the same predicates a resolve context does, and + * matches a variant only where it pins that condition. `search` is free text over pinned + * values; `sort` orders by one pin. + * + * Offset paging up to the search index's window, then the `cursor` from `next`. + * + */ + 'post'( + parameters?: Parameters | null, + data?: Paths.$ListConditionalVariants.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + } + ['/v1/conditional-pricing/{slug}/entities/{entity_id}/variants:tree']: { + /** + * $getConditionalVariantTree - $getConditionalVariantTree + * + * The variants list, each row carrying the version in effect at `as_of` and a `status` saying + * whether that version is `active` or still `scheduled`. * - * Returns the version of this variant that is currently in effect — the one with the latest - * `valid_from` at or before now. + * Takes everything the variants list takes, plus `as_of`. `size` is clamped at 100, and a + * variant mid-delete is omitted from `results`. * - * The "open this variant" read: no date arithmetic is asked of the caller, and what comes back - * carries the `_revision` a write to that version has to be sent with, so an editing screen can - * load and save without working out which version it is looking at. + */ + 'post'( + parameters?: Parameters | null, + data?: Paths.$GetConditionalVariantTree.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + } + ['/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}']: { + /** + * $getActiveConditionalVariantVersion - $getActiveConditionalVariantVersion * - * What is returned is the version's own attribute overrides, not the base entity overlaid with - * them. Composing the two is what `:resolve` answers. + * Returns the version of this variant in effect now — the latest `valid_from` at or before now + * — with the `_revision` a write to it must carry. * - * A variant staged ahead of its launch has versions but none of them in effect, and is reported - * as having none rather than as not existing — the two are fixed differently. + * These are the version's own overrides; `:resolve` composes them onto the entity. * */ 'get'( @@ -14317,20 +21344,11 @@ export interface PathsDictionary { /** * $replaceActiveConditionalVariantVersion - $replaceActiveConditionalVariantVersion * - * Replaces the values of the version currently in effect, wholesale. - * - * The body is the complete set of attribute overrides: an attribute the variant may override and - * that is absent from it stops being overridden. Attributes the variant may **not** override are - * ignored where the body carries them, and their stored value is kept rather than dropped — a - * routine full-snapshot write must not erase an override the moment its attribute's flag happens - * to be off. + * Replaces the values of the version in effect. The body is the complete set of overrides: an + * overridable attribute absent from it stops being overridden, and one the variant may not + * override keeps its stored value. * - * Editing the version in effect is the ordinary way a live price is corrected, and warns about - * nothing: what changes is what that version *says*, not which version is in effect. - * - * Neither `valid_from` nor `conditions` can be changed here. Both are accepted when they match - * what is stored, so a client building its body from the version it loaded need not strip them - * out first, and both are refused when they name something else. + * `valid_from` and `conditions` are accepted only unchanged. * */ 'put'( @@ -14341,15 +21359,8 @@ export interface PathsDictionary { /** * $patchActiveConditionalVariantVersion - $patchActiveConditionalVariantVersion * - * Changes only the fields it names on the version currently in effect. - * - * Everything the body does not mention is left as stored — the "just nudge this number" write. A - * `null` is a value like any other rather than a deletion; a client that wants an attribute to - * stop being overridden sends the complete snapshot without it through `PUT`. - * - * Attempting to change a pinned condition value is refused here in particular: a partial update - * is the path a caller reaches for by accident, and a variant's conditions are the situation it - * applies to, which the orders and contracts pinning it depend on not shifting. + * Changes only the fields it names on the version in effect. `null` sets a value rather than + * removing an override; use the replace operation to remove one. * */ 'patch'( @@ -14360,23 +21371,11 @@ export interface PathsDictionary { /** * $deleteConditionalVariant - $deleteConditionalVariant * - * Removes one variant of a conditional entity: the condition tuple it holds, its registration - * in the search index, and every version it accumulated. - * - * Two phases. The first frees the tuple and deregisters the variant, and is what makes the - * combination of condition values immediately reusable — the second removes the version rows in - * batches afterwards. A response arrives only once both have finished for this request, but the - * tuple is reusable from the moment the first completes, whether or not the second did: a - * variant with more versions than one transaction can carry is the ordinary case, not an edge - * one. An interrupted delete is safe to send again; it picks up where it stopped. + * Removes one variant: its condition tuple, its index entry and all its versions. The tuple + * becomes reusable, and an interrupted delete is safe to send again. * - * Nothing is archived. A variant an order or contract pins stops resolving, and hydration drops - * the reference leniently rather than failing the read. - * - * This removes the **variant**, not one of its versions. To remove a single version, name it on - * `…/variants/{variant_id}/versions/{valid_from}` — including the one currently in effect, which - * deliberately has no "delete whichever is live" shorthand: that is exactly the write nobody - * should be able to ask for without saying which version they meant. + * Orders and contracts pinning the variant stop resolving. To remove a single version, address + * it under `versions/{valid_from}`. * */ 'delete'( @@ -14387,27 +21386,26 @@ export interface PathsDictionary { } ['/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions']: { /** - * $appendConditionalVariantVersion - $appendConditionalVariantVersion + * $listConditionalVariantVersions - $listConditionalVariantVersions * - * Appends a version to a variant: a new set of values taking effect at its own instant. + * Lists one variant's versions. Cursor paging only: a page may be short or empty and still + * carry a `next`, so page until `next` is absent. A cursor is bound to one variant and one + * `order`. * - * This is how a price changes. No version carries an end date and nothing is superseded - * explicitly — the version in effect at an instant is simply the one with the latest `valid_from` - * at or before it, so appending a later version is the whole of "this is the new price from then - * on". A version dated in the future is staged and excluded from resolution until its date. - * - * **A version is never refused for being late.** A `valid_from` in the past is written like any - * other and answered with warnings in `warnings` naming what it moved — what resolves now, what a - * past-dated read returns, or both. Correcting a price that took effect last week is ordinary - * work; the alternative, deleting and recreating the variant, breaks every order and contract - * pinning its id. + */ + 'get'( + parameters?: Parameters | null, + data?: any, + config?: AxiosRequestConfig + ): OperationResponse + /** + * $appendConditionalVariantVersion - $appendConditionalVariantVersion * - * What is refused is appending at a `valid_from` the variant already has: that write means either - * "replace it" or "and also this", and only the caller knows which. The two operations both - * exist, on the dated version path. + * Appends a version taking effect at its own instant. The version in effect at any instant is + * the one with the latest `valid_from` at or before it; a future one is staged until its date. * - * The variant's `conditions` are its identity and are fixed at creation; they may be sent back - * unchanged but never changed. + * A past `valid_from` is accepted and reported in `warnings`. One the variant already has is + * refused — replace or patch that version instead. * */ 'post'( @@ -14420,12 +21418,7 @@ export interface PathsDictionary { /** * $getConditionalVariantVersion - $getConditionalVariantVersion * - * Returns one specific version of a variant, by the instant it takes effect — what a form editing - * that version loads. - * - * Exact, never nearest: an instant the variant has no version at is a not-found rather than the - * version that would be in effect at it. That question is the shorthand read's, or `:resolve`'s. - * + * Returns one version by the instant it takes effect. Exact, never nearest. */ 'get'( parameters?: Parameters | null, @@ -14435,16 +21428,8 @@ export interface PathsDictionary { /** * $replaceConditionalVariantVersion - $replaceConditionalVariantVersion * - * Replaces one version's values wholesale, addressed by its `valid_from`. - * - * Editable whatever its date, at both ends of the timeline: a scheduled version must stay - * editable so a staged price can be corrected before it goes live rather than accumulating dead - * versions beside it, and a past one must stay editable because correcting history is ordinary - * work. Writing a superseded version is answered with a warning naming what a past-dated read now - * returns; it is not refused. - * - * Attributes the variant may not override are ignored where the body carries them, and their - * stored value is preserved rather than dropped. + * Replaces one version's values, whatever its date. Attributes the variant may not override + * keep their stored value. Writing a superseded version is reported in `warnings`. * */ 'put'( @@ -14455,12 +21440,7 @@ export interface PathsDictionary { /** * $patchConditionalVariantVersion - $patchConditionalVariantVersion * - * Changes only the fields it names on one version, addressed by its `valid_from`. - * - * Everything the body does not mention is left as stored. A partial update that tries to change a - * pinned condition value is refused: condition values are immutable after a variant is created, - * and this is the path that rule is most likely to be broken on by accident. - * + * Changes only the fields it names on one version. */ 'patch'( parameters?: Parameters | null, @@ -14470,18 +21450,8 @@ export interface PathsDictionary { /** * $deleteConditionalVariantVersion - $deleteConditionalVariantVersion * - * Removes one version of a variant. - * - * Withdrawing a scheduled adjustment is what this is for, and deleting a future version warns - * about nothing — nothing that has resolved, or could have resolved, changes. Deleting a version - * that has taken effect is allowed too and answered with a warning: it changes what a past-dated - * read returns, and if it was the version in effect it changes what resolves now. - * - * **A variant's last remaining version cannot be deleted.** Such a variant would still hold its - * condition tuple and still be selectable, and then resolve to nothing — which is a variant delete - * wearing a version delete's clothes. Delete the variant instead; that frees the tuple too. - * - * The variant itself is untouched: it keeps its conditions, its tuple and its place in the index. + * Removes one version. What the removal moves is reported in `warnings`. A variant's last + * remaining version cannot be removed — delete the variant instead. * */ 'delete'( @@ -14490,6 +21460,51 @@ export interface PathsDictionary { config?: AxiosRequestConfig ): OperationResponse } + ['/v1/conditional-pricing/{slug}/variants:batchUpsert']: { + /** + * $batchUpsertConditionalVariants - $batchUpsertConditionalVariants + * + * Writes up to 100 variants or versions in one call. Each item names its own entity, so one + * call can span a tariff hierarchy, and addresses a variant by condition tuple rather than by + * id — the id it created or found is on the result entry. + * + * Each item's outcome is derived from what is stored: an unknown tuple is `variant_created`, a + * known tuple with no version at the item's `valid_from` is `version_created`, an existing + * version there is `updated`, and a write matching what is stored is `skipped`. An item + * without `valid_from` is a last-write-wins write with no `skipped` detection. + * + * Items addressing the same `(entity_id, conditions)` apply in array order; the rest run in + * parallel. No cross-item rollback, and no `_revision` guard. + * + */ + 'post'( + parameters?: Parameters | null, + data?: Paths.$BatchUpsertConditionalVariants.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + } + ['/v1/conditional-pricing/{slug}/variants:batchDelete']: { + /** + * $batchDeleteConditionalVariants - $batchDeleteConditionalVariants + * + * Removes up to 100 variants or versions in one call. An item carrying `valid_from` removes + * that version; one without it removes the whole variant. + * + * Each item addresses its variant by `variant_id` beside its `entity_id`, or by the condition + * tuple it pins, never both. Use ids once a condition has left the schema, since its tuple can + * no longer be canonicalized. + * + * Items addressing the same variant apply in array order, resolved to ids first; the rest run + * in parallel. An item addressing a missing variant or version is `skipped`, and the call is + * safe to send again. + * + */ + 'post'( + parameters?: Parameters | null, + data?: Paths.$BatchDeleteConditionalVariants.RequestBody, + config?: AxiosRequestConfig + ): OperationResponse + } } export type Client = OpenAPIClient @@ -14513,6 +21528,20 @@ export type BasePriceItemCommon = Components.Schemas.BasePriceItemCommon; export type BasePriceItemDto = Components.Schemas.BasePriceItemDto; export type BasicAuthCredentials = Components.Schemas.BasicAuthCredentials; export type BasicAuthIntegration = Components.Schemas.BasicAuthIntegration; +export type BatchDeleteByConditions = Components.Schemas.BatchDeleteByConditions; +export type BatchDeleteByVariantId = Components.Schemas.BatchDeleteByVariantId; +export type BatchDeleteCounts = Components.Schemas.BatchDeleteCounts; +export type BatchDeleteItem = Components.Schemas.BatchDeleteItem; +export type BatchDeleteOutcome = Components.Schemas.BatchDeleteOutcome; +export type BatchDeleteResult = Components.Schemas.BatchDeleteResult; +export type BatchDeleteResultEntry = Components.Schemas.BatchDeleteResultEntry; +export type BatchDeleteVariantsRequest = Components.Schemas.BatchDeleteVariantsRequest; +export type BatchUpsertCounts = Components.Schemas.BatchUpsertCounts; +export type BatchUpsertItem = Components.Schemas.BatchUpsertItem; +export type BatchUpsertOutcome = Components.Schemas.BatchUpsertOutcome; +export type BatchUpsertResult = Components.Schemas.BatchUpsertResult; +export type BatchUpsertResultEntry = Components.Schemas.BatchUpsertResultEntry; +export type BatchUpsertVariantsRequest = Components.Schemas.BatchUpsertVariantsRequest; export type BillingPeriod = Components.Schemas.BillingPeriod; export type CartDto = Components.Schemas.CartDto; export type CashbackAmount = Components.Schemas.CashbackAmount; @@ -14578,10 +21607,13 @@ export type GasMarketAreaDetails = Components.Schemas.GasMarketAreaDetails; export type HistoricMarketPriceRecord = Components.Schemas.HistoricMarketPriceRecord; export type HistoricMarketPricesResult = Components.Schemas.HistoricMarketPricesResult; export type HydratedCompositePrice = Components.Schemas.HydratedCompositePrice; +export type InertOverride = Components.Schemas.InertOverride; +export type InertOverrideReason = Components.Schemas.InertOverrideReason; export type IntegrationAuthCredentials = Components.Schemas.IntegrationAuthCredentials; export type IntegrationCredentialsResult = Components.Schemas.IntegrationCredentialsResult; export type IntegrationId = Components.Schemas.IntegrationId; export type JourneyContext = Components.Schemas.JourneyContext; +export type ListVariantsRequest = Components.Schemas.ListVariantsRequest; export type MarketParticipant = Components.Schemas.MarketParticipant; export type MarkupPricingModel = Components.Schemas.MarkupPricingModel; export type MetaData = Components.Schemas.MetaData; @@ -14600,6 +21632,7 @@ export type OrderStatus = Components.Schemas.OrderStatus; export type PatchVersionRequest = Components.Schemas.PatchVersionRequest; export type PaymentMethod = Components.Schemas.PaymentMethod; export type PinnedConditions = Components.Schemas.PinnedConditions; +export type PinnedResolveOptions = Components.Schemas.PinnedResolveOptions; export type PortalContext = Components.Schemas.PortalContext; export type PowerMarketAreaDetails = Components.Schemas.PowerMarketAreaDetails; export type PowerMeterType = Components.Schemas.PowerMeterType; @@ -14634,6 +21667,9 @@ export type RecurrenceAmountDto = Components.Schemas.RecurrenceAmountDto; export type RecurrenceAmountWithTax = Components.Schemas.RecurrenceAmountWithTax; export type RedeemedPromo = Components.Schemas.RedeemedPromo; export type ReplaceVersionRequest = Components.Schemas.ReplaceVersionRequest; +export type ReportedError = Components.Schemas.ReportedError; +export type ResolveByContextRequest = Components.Schemas.ResolveByContextRequest; +export type ResolveByPinRequest = Components.Schemas.ResolveByPinRequest; export type ResolveConditionalEntityRequest = Components.Schemas.ResolveConditionalEntityRequest; export type ResolveContext = Components.Schemas.ResolveContext; export type ResolveOptions = Components.Schemas.ResolveOptions; @@ -14665,9 +21701,18 @@ export type TotalDetails = Components.Schemas.TotalDetails; export type TypeGetAg = Components.Schemas.TypeGetAg; export type ValidateAvailabilityFileError = Components.Schemas.ValidateAvailabilityFileError; export type ValidateAvailabilityFileResult = Components.Schemas.ValidateAvailabilityFileResult; +export type VariantConditionFilter = Components.Schemas.VariantConditionFilter; export type VariantConditions = Components.Schemas.VariantConditions; +export type VariantList = Components.Schemas.VariantList; +export type VariantListRow = Components.Schemas.VariantListRow; +export type VariantTree = Components.Schemas.VariantTree; +export type VariantTreeRequest = Components.Schemas.VariantTreeRequest; +export type VariantTreeRow = Components.Schemas.VariantTreeRow; +export type VariantTreeRowStatus = Components.Schemas.VariantTreeRowStatus; export type VariantValues = Components.Schemas.VariantValues; export type VariantVersion = Components.Schemas.VariantVersion; -export type VariantWriteWarning = Components.Schemas.VariantWriteWarning; -export type VersionWriteWarning = Components.Schemas.VersionWriteWarning; +export type VariantVersionList = Components.Schemas.VariantVersionList; +export type VariantVersionSnapshot = Components.Schemas.VariantVersionSnapshot; +export type VersionMoved = Components.Schemas.VersionMoved; +export type WriteWarning = Components.Schemas.WriteWarning; export type WrittenVariantVersion = Components.Schemas.WrittenVariantVersion; diff --git a/clients/pricing-client/src/openapi.json b/clients/pricing-client/src/openapi.json index 4540dc8e..b4da888b 100644 --- a/clients/pricing-client/src/openapi.json +++ b/clients/pricing-client/src/openapi.json @@ -3422,7 +3422,7 @@ }, "/v1/conditional-pricing/{slug}/condition-sets": { "get": { - "description": "Returns the condition sets built in for one conditional entity type: the situations a\nconditional Product, Price or Coupon is commonly varied by, ready to be copied into that\nschema's `conditions` array and extended or modified from there.\n\nWhich sets exist depends on the schema — an offer window is a Product's dimension, a delivery\narea is a Price's and a Coupon's — so only the sets built in for `slug` are returned.\n\nStatic, read-only reference data. The catalog is the same for every organization and is not\napplied to any schema by this endpoint — adding conditions to a schema stays an Entity API\nwrite.\n", + "description": "Returns the condition sets built in for one conditional entity type, ready to copy into that schema's `conditions` array. Read-only, and the same for every organization.", "operationId": "$getConditionSets", "summary": "$getConditionSets", "tags": [ @@ -3466,7 +3466,7 @@ }, "/v1/conditional-pricing:resolve": { "post": { - "description": "Resolves which of a conditional entity's variants apply to a situation, and returns each one\ncomposed: the base entity overlaid with the values of the version in effect at `as_of`.\n\nResolution is two selections in a fixed order — the variant, by matching `context` against\nthe conditions each variant pins; then the version, by `as_of`. It is always scoped to one\nlogical entity, so it stays a cheap, predictable lookup rather than an open search.\n\nMatching follows two rules worth knowing before assembling a context. A condition a variant\ndoes **not** pin matches any value, which is what lets a condition be added to a schema\nwithout breaking the variants that already exist. A condition **missing from `context`**,\nhowever, does not satisfy one a variant pinned: an incomplete integration resolves to\nnothing rather than silently matching another segment's variants.\n\nWhen nothing matches, the entity's `default` variant is returned if it has one. There is no\nimplicit fallback to the unmodified base entity — its values are the ones no variant\noverrode, which is not an answer to \"what applies here\".\n\nAvailability is a separate mechanism and is never consulted here.\n", + "description": "Returns the variants of one conditional entity that apply, each composed: the base entity\noverlaid with the version in effect at `as_of`.\n\nSelect the variant either by `context`, matched against the conditions each variant pins, or\nby `variant_id`. Exactly one of the two. A condition a variant leaves unpinned matches any\nvalue; a condition absent from `context` matches only variants that leave it unpinned.\n\nWhen no variant matches, the entity's `default` variant is returned, or `results` is empty.\n`options.hydrate` replaces relation references with the entities they reference.\n", "operationId": "$resolveConditionalEntity", "summary": "$resolveConditionalEntity", "tags": [ @@ -3478,23 +3478,127 @@ "application/json": { "schema": { "$ref": "#/components/schemas/ResolveConditionalEntityRequest" + }, + "examples": { + "Pin a variant at a recorded instant": { + "summary": "The numbers an order recorded", + "value": { + "schema": "price", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "as_of": "2026-01-01T00:00:00Z" + } + }, + "Pin a variant as it stands now": { + "summary": "What a contract is billed at today", + "value": { + "schema": "price", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045" + } + }, + "Match a context, hydrating relations": { + "summary": "A composite price and its components in one round trip", + "value": { + "schema": "price", + "entity_id": "price-composite-9f2", + "context": { + "postal_code": "46045" + }, + "options": { + "hydrate": true + } + } + } } } } }, "responses": { "200": { - "description": "The variants that apply, each composed with the version in effect. Empty when nothing\napplies and the entity has no `default` variant. With `resolve_one`, exactly one result.\n", + "description": "The variants that apply, each composed with the version in effect. Empty when none\napplies and the entity has no `default` variant.\n", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResolvedVariants" + }, + "examples": { + "A hydrated composite price": { + "summary": "The component entities the variant's override names, fetched after composition", + "value": { + "results": [ + { + "_id": "price-composite-9f2", + "_variant_id": "var-46045", + "_version_valid_from": "2027-01-01T00:00:00.000Z", + "_conditions": { + "postal_code": "46045", + "default": false + }, + "_inert_overrides": [], + "_schema": "price", + "is_composite_price": true, + "price_components": [ + { + "_id": "price-base-fee-46045", + "_schema": "price", + "unit_amount": 1290, + "unit_amount_currency": "EUR", + "$relation": { + "entity_id": "price-base-fee-46045", + "attribute": "price_components" + } + }, + { + "_id": "price-kwh-46045", + "_schema": "price", + "unit_amount": 32, + "unit_amount_currency": "EUR", + "$relation": { + "entity_id": "price-kwh-46045", + "attribute": "price_components" + } + } + ] + } + ] + } + }, + "A variant carrying overrides that did not apply": { + "summary": "`unit_amount_currency` reads as the entity's own value, and `_inert_overrides` says why each stored override was passed over", + "value": { + "results": [ + { + "_id": "price-sp26d1yo", + "_variant_id": "var-46045", + "_version_valid_from": "2027-01-01T00:00:00.000Z", + "_conditions": { + "postal_code": "46045", + "default": false + }, + "_inert_overrides": [ + { + "attribute": "unit_amount_currency", + "reason": "ATTRIBUTE_NOT_OVERRIDABLE" + }, + { + "attribute": "legacy_surcharge", + "reason": "ATTRIBUTE_UNDECLARED" + } + ], + "_schema": "price", + "unit_amount": 2499, + "unit_amount_currency": "EUR" + } + ] + } + } } } } }, "400": { - "description": "The context is not usable against this schema: it names an undefined condition\n(`CONDITION_UNDEFINED`), applies an operator the condition's type does not support\n(`OPERATOR_UNSUPPORTED`), carries a value malformed for its type (`CONTEXT_FORMAT_INVALID`),\nor selects more variants than one response may carry (`TOO_MANY_MATCHES`).\n", + "description": "`CONDITION_UNDEFINED`, `OPERATOR_UNSUPPORTED`, `CONTEXT_FORMAT_INVALID`,\n`DEFAULT_MARKER_RESERVED`, `TOO_MANY_MATCHES`, `VALID_FROM_INVALID`,\n`ENTITY_TYPE_MISMATCH`. A body carrying both `context` and `variant_id`, or neither,\nfails validation and carries no `code`.\n", "content": { "application/json": { "schema": { @@ -3504,7 +3608,7 @@ } }, "404": { - "description": "No such schema or entity, or — with `resolve_one` — nothing applied and the entity has no\n`default` variant (`NOT_FOUND`).\n", + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`, and on the pinned branch `VARIANT_NOT_FOUND` or\n`NO_ACTIVE_VERSION`. With `resolve_one`, `NO_MATCHES`; without it, no match is a `200`\ncarrying an empty `results`.\n", "content": { "application/json": { "schema": { @@ -3514,7 +3618,7 @@ } }, "409": { - "description": "Several variants apply while a single result was requested (`AMBIGUOUS_RESOLUTION`); the\ncandidates are in `details`.\n", + "description": "`AMBIGUOUS_RESOLUTION`, `CONDITION_UNREADABLE`, `VARIANT_PIN_UNDECLARED`,\n`ENTITY_NOT_CONDITIONAL`.\n", "content": { "application/json": { "schema": { @@ -3528,7 +3632,7 @@ }, "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants": { "post": { - "description": "Creates one variant of a conditional entity, together with the first version carrying its\nvalues. Never two calls: a variant that existed without a version would be an entity holding\na condition tuple it cannot answer with.\n\nThe body pins the situation the variant applies to. Pins are exact values only — predicates\nare a read-side concept and are rejected here — and are stored canonicalized for their\ncondition's type, so two spellings of one instant, or one town written two ways, are one\nvariant rather than two that no context can tell apart.\n\nThree write rules are worth knowing before the first call:\n\n- A variant must pin at least one condition or be marked `default`. A variant pinning nothing\n would be a universal wildcard matching every resolve, which is a far more dangerous thing\n than a fallback and far easier to create by accident.\n- `default` is a property of the variant, set by the `default` flag, and is never a value in\n `conditions` — not even `false`. A `default` variant cannot pin anything else, and an entity\n can have only one, enforced by the ordinary condition-tuple guard rather than by a rule of\n its own. Any entity may have one; nothing is declared in the schema to allow it.\n- Condition values are immutable afterwards. A variant's identity is the situation it applies\n to, and orders and contracts pin it. **A condition added to a schema that already has\n variants is effectively one-way**: every existing variant is a wildcard on the new\n dimension, but the first variant that pins it is ambiguous against all of them, and\n retro-pinning the others is blocked by this same rule.\n\nAttribute values are applied only for attributes currently carrying `overridable_attribute`.\nMetadata and non-overridable fields present in the body are ignored rather than rejected, so a\nclient working from a slightly stale schema snapshot still succeeds.\n\n`variant_id` is always server-generated and returned, and is not accepted in the body — the\nrequest schema admits no such property. It is the durable key orders and contracts pin, so it\ncannot be something two independent importers could collide on.\n", + "description": "Creates one variant together with its first version.\n\n`conditions` pins the situation the variant applies to, as exact values. A variant must pin\nat least one condition or be marked `default`, of which an entity may have one, and its\ncondition values are fixed once created.\n\nValues are stored only for attributes carrying `overridable_attribute`; the rest are\nreported in `warnings` rather than rejected. `variant_id` is server-generated.\n", "operationId": "$createConditionalVariant", "summary": "$createConditionalVariant", "tags": [ @@ -3573,12 +3677,51 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CreatedVariant" + }, + "examples": { + "A body naming attributes this variant may not override": { + "summary": "The write succeeded, and the attributes the warning names are absent from `values`", + "value": { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 2499 + }, + "_created_at": "2026-12-01T09:15:00.000Z", + "_updated_at": "2026-12-01T09:15:00.000Z", + "_revision": 1, + "warnings": [ + { + "code": "ATTRIBUTES_NOT_APPLIED", + "message": "The values sent for 2 attributes were not applied: unit_amount_currency, legacy_surcharge", + "details": { + "attributes": [ + { + "attribute": "unit_amount_currency", + "reason": "ATTRIBUTE_NOT_OVERRIDABLE" + }, + { + "attribute": "legacy_surcharge", + "reason": "ATTRIBUTE_UNDECLARED" + } + ] + } + } + ] + } + } } } } }, "400": { - "description": "The variant cannot be created as described: it pins nothing and is not the default, pins\na condition the schema does not declare (`CONDITION_UNDEFINED`), pins a `select` value\noutside the vocabulary the condition declares (`CONDITION_VALUE_INVALID`), pins the\nfallback marker directly under either of its names (`default` or `_default`), carries a\nvalue malformed for its condition's type, or the entity already holds every variant it\nmay hold.\n", + "description": "`VARIANT_UNPINNED`, `CONDITION_UNDEFINED`, `CONDITION_VALUE_INVALID`,\n`PIN_FORMAT_INVALID`, `DEFAULT_MARKER_RESERVED`, `DEFAULT_VARIANT_PINS_CONDITIONS`,\n`VALID_FROM_INVALID`, `VALUE_UNSTORABLE`, `IDENTIFIER_INVALID`, `ENTITY_TYPE_MISMATCH`.\n", "content": { "application/json": { "schema": { @@ -3587,8 +3730,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "No such schema, or no such entity (`NOT_FOUND`).", + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`.", "content": { "application/json": { "schema": { @@ -3598,7 +3751,7 @@ } }, "409": { - "description": "Another variant of this entity already pins this exact combination of condition values\n(`TUPLE_CONFLICT`, naming it in `details.conflicting_variant_id`) — which is also how a\nsecond `default` variant is refused — or the entity's items are being written\nconcurrently (`WRITE_CONFLICT`, retryable).\n", + "description": "`TUPLE_CONFLICT` (also how a second `default` variant is refused), `WRITE_CONFLICT`,\n`CONDITION_UNREADABLE`, `CONDITION_UNCONFIGURED`, `VARIANT_LIMIT_REACHED`,\n`ENTITY_NOT_CONDITIONAL`.\n", "content": { "application/json": { "schema": { @@ -3610,11 +3763,11 @@ } } }, - "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}": { - "get": { - "description": "Returns the version of this variant that is currently in effect — the one with the latest\n`valid_from` at or before now.\n\nThe \"open this variant\" read: no date arithmetic is asked of the caller, and what comes back\ncarries the `_revision` a write to that version has to be sent with, so an editing screen can\nload and save without working out which version it is looking at.\n\nWhat is returned is the version's own attribute overrides, not the base entity overlaid with\nthem. Composing the two is what `:resolve` answers.\n\nA variant staged ahead of its launch has versions but none of them in effect, and is reported\nas having none rather than as not existing — the two are fixed differently.\n", - "operationId": "$getActiveConditionalVariantVersion", - "summary": "$getActiveConditionalVariantVersion", + "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants:list": { + "post": { + "description": "Lists a conditional entity's variants and the conditions each one pins. A `POST` because the\ncondition filter is a structured object; nothing is written. The body is required, so send\n`{}` for the first page.\n\n`conditions` filters on the pins, taking the same predicates a resolve context does, and\nmatches a variant only where it pins that condition. `search` is free text over pinned\nvalues; `sort` orders by one pin.\n\nOffset paging up to the search index's window, then the `cursor` from `next`.\n", + "operationId": "$listConditionalVariants", + "summary": "$listConditionalVariants", "tags": [ "Conditional Pricing API" ], @@ -3622,7 +3775,7 @@ { "in": "path", "name": "slug", - "description": "The conditional entity type this variant belongs to", + "description": "The conditional entity type the variants belong to", "schema": { "$ref": "#/components/schemas/ConditionalEntitySlug" }, @@ -3632,37 +3785,107 @@ { "in": "path", "name": "entity_id", - "description": "The conditional entity the variant belongs to", + "description": "The conditional entity whose variants to list", "schema": { "type": "string" }, "required": true, "example": "price-sp26d1yo" - }, - { - "in": "path", - "name": "variant_id", - "description": "The variant whose timeline this call addresses", - "schema": { - "type": "string" - }, - "required": true, - "example": "var-46045" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListVariantsRequest" + }, + "examples": { + "The first page": { + "summary": "The smallest valid body — the first ten variants, in `variant_id` order", + "value": {} + }, + "Find the entity's fallback variant": { + "summary": "The variant served when nothing else applies", + "value": { + "conditions": { + "default": true + } + } + }, + "Filter, search and sort together": { + "summary": "Variants pinning a consumption band in either segment, ordered by postal code", + "value": { + "conditions": { + "segment": { + "in": [ + "private", + "commercial" + ] + }, + "consumption": { + "lt": 5000 + } + }, + "search": "460", + "sort": "conditions.postal_code:asc", + "size": 25 + } + }, + "Continue past the offset window": { + "summary": "What a caller sends instead of the `from` that was refused", + "value": { + "cursor": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0", + "sort": "conditions.postal_code:asc", + "size": 25 + } + } + } + } + } + }, "responses": { "200": { - "description": "The version, as stored", + "description": "The page of matching variants, and how many match in total", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VariantVersion" + "$ref": "#/components/schemas/VariantList" + }, + "examples": { + "A page of a postal-code price": { + "summary": "Two of 8,128 matches, with the cursor that continues the listing", + "value": { + "hits": 8128, + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "46045", + "default": false + } + }, + { + "variant_id": "var-50667", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "50667", + "default": false + } + } + ], + "next": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" + } + } } } } }, "400": { - "description": "Invalid request, e.g. the slug names no conditional entity type.\n", + "description": "`CONDITION_UNDEFINED`, `OPERATOR_UNSUPPORTED`, `CONTEXT_FORMAT_INVALID`, `SORT_INVALID`,\n`OFFSET_WINDOW_EXCEEDED`, `CURSOR_INVALID`, `ENTITY_TYPE_MISMATCH`.\n", "content": { "application/json": { "schema": { @@ -3671,8 +3894,28 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "No such variant under this schema, or it has no version at the instant addressed\n(`NOT_FOUND`). A variant whose versions are all still scheduled has none in effect, which is\nreported as such rather than as a missing variant.\n", + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`. An entity with no variants is a `200` carrying\nan empty `results` and `hits: 0`.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } + }, + "409": { + "description": "`CONDITION_UNREADABLE`, raised only where the filter or `sort` names that condition, and\n`ENTITY_NOT_CONDITIONAL`.\n", "content": { "application/json": { "schema": { @@ -3682,11 +3925,13 @@ } } } - }, - "put": { - "description": "Replaces the values of the version currently in effect, wholesale.\n\nThe body is the complete set of attribute overrides: an attribute the variant may override and\nthat is absent from it stops being overridden. Attributes the variant may **not** override are\nignored where the body carries them, and their stored value is kept rather than dropped — a\nroutine full-snapshot write must not erase an override the moment its attribute's flag happens\nto be off.\n\nEditing the version in effect is the ordinary way a live price is corrected, and warns about\nnothing: what changes is what that version *says*, not which version is in effect.\n\nNeither `valid_from` nor `conditions` can be changed here. Both are accepted when they match\nwhat is stored, so a client building its body from the version it loaded need not strip them\nout first, and both are refused when they name something else.\n", - "operationId": "$replaceActiveConditionalVariantVersion", - "summary": "$replaceActiveConditionalVariantVersion", + } + }, + "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants:tree": { + "post": { + "description": "The variants list, each row carrying the version in effect at `as_of` and a `status` saying\nwhether that version is `active` or still `scheduled`.\n\nTakes everything the variants list takes, plus `as_of`. `size` is clamped at 100, and a\nvariant mid-delete is omitted from `results`.\n", + "operationId": "$getConditionalVariantTree", + "summary": "$getConditionalVariantTree", "tags": [ "Conditional Pricing API" ], @@ -3694,7 +3939,7 @@ { "in": "path", "name": "slug", - "description": "The conditional entity type this variant belongs to", + "description": "The conditional entity type the variants belong to", "schema": { "$ref": "#/components/schemas/ConditionalEntitySlug" }, @@ -3704,22 +3949,12 @@ { "in": "path", "name": "entity_id", - "description": "The conditional entity the variant belongs to", + "description": "The conditional entity whose variants to list", "schema": { "type": "string" }, "required": true, "example": "price-sp26d1yo" - }, - { - "in": "path", - "name": "variant_id", - "description": "The variant whose timeline this call addresses", - "schema": { - "type": "string" - }, - "required": true, - "example": "var-46045" } ], "requestBody": { @@ -3727,24 +3962,111 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ReplaceVersionRequest" + "$ref": "#/components/schemas/VariantTreeRequest" + }, + "examples": { + "The screen as it opens": { + "summary": "The first page as of now, ordered by postal code", + "value": { + "sort": "conditions.postal_code:asc", + "size": 25 + } + }, + "The screen at a future date": { + "summary": "The table once next year's versions take effect", + "value": { + "as_of": "2027-03-15T00:00:00Z", + "conditions": { + "postal_code": { + "in": [ + "46045", + "50667" + ] + } + }, + "size": 25 + } + } } } } }, "responses": { "200": { - "description": "The version, as the write left it, together with anything the write moved", + "description": "The page of matching variants, each with the version its `status` names", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WrittenVariantVersion" + "$ref": "#/components/schemas/VariantTree" + }, + "examples": { + "One live row and one staged row": { + "summary": "A variant whose version is in effect, beside one whose first version is still ahead of `as_of`", + "value": { + "hits": 8128, + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "46045", + "default": false + }, + "status": "active", + "version": { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2026-01-01T00:00:00.000Z", + "values": { + "unit_amount": 3261, + "unit_amount_decimal": "32.61" + }, + "_created_at": "2025-11-14T09:12:44.101Z", + "_updated_at": "2025-11-14T09:12:44.101Z" + } + }, + { + "variant_id": "var-50667", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "50667", + "default": false + }, + "status": "scheduled", + "version": { + "variant_id": "var-50667", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "50667", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 3412, + "unit_amount_decimal": "34.12" + }, + "_created_at": "2026-08-02T16:40:03.882Z", + "_updated_at": "2026-08-02T16:40:03.882Z" + } + } + ], + "next": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" + } + } } } } }, "400": { - "description": "The write cannot be applied as described: it would move the version it addresses to another\n`valid_from`, or change the conditions its variant is pinned to — both identity rather than\ncontent, and both fixed at creation. Also when `_revision` is missing or is not a revision\nmarker.\n", + "description": "`CONDITION_UNDEFINED`, `OPERATOR_UNSUPPORTED`, `CONTEXT_FORMAT_INVALID`, `SORT_INVALID`,\n`OFFSET_WINDOW_EXCEEDED`, `CURSOR_INVALID`, `VALID_FROM_INVALID`,\n`ENTITY_TYPE_MISMATCH`.\n", "content": { "application/json": { "schema": { @@ -3753,8 +4075,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "No such variant under this schema, or it has no version at the instant addressed\n(`NOT_FOUND`). A variant whose versions are all still scheduled has none in effect, which is\nreported as such rather than as a missing variant.\n", + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`. An entity with no variants is a `200` carrying\nan empty `results` and `hits: 0`.\n", "content": { "application/json": { "schema": { @@ -3764,7 +4096,7 @@ } }, "409": { - "description": "The version has been written since `_revision` was read (`WRITE_CONFLICT`, retryable after\nre-reading the version).\n", + "description": "`CONDITION_UNREADABLE`, raised only where the filter or `sort` names that condition, and\n`ENTITY_NOT_CONDITIONAL`.\n", "content": { "application/json": { "schema": { @@ -3774,11 +4106,13 @@ } } } - }, - "patch": { - "description": "Changes only the fields it names on the version currently in effect.\n\nEverything the body does not mention is left as stored — the \"just nudge this number\" write. A\n`null` is a value like any other rather than a deletion; a client that wants an attribute to\nstop being overridden sends the complete snapshot without it through `PUT`.\n\nAttempting to change a pinned condition value is refused here in particular: a partial update\nis the path a caller reaches for by accident, and a variant's conditions are the situation it\napplies to, which the orders and contracts pinning it depend on not shifting.\n", - "operationId": "$patchActiveConditionalVariantVersion", - "summary": "$patchActiveConditionalVariantVersion", + } + }, + "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}": { + "get": { + "description": "Returns the version of this variant in effect now — the latest `valid_from` at or before now\n— with the `_revision` a write to it must carry.\n\nThese are the version's own overrides; `:resolve` composes them onto the entity.\n", + "operationId": "$getActiveConditionalVariantVersion", + "summary": "$getActiveConditionalVariantVersion", "tags": [ "Conditional Pricing API" ], @@ -3814,29 +4148,19 @@ "example": "var-46045" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PatchVersionRequest" - } - } - } - }, "responses": { "200": { - "description": "The version, as the write left it, together with anything the write moved", + "description": "The version, as stored", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WrittenVariantVersion" + "$ref": "#/components/schemas/VariantVersion" } } } }, "400": { - "description": "The write cannot be applied as described: it would move the version it addresses to another\n`valid_from`, or change the conditions its variant is pinned to — both identity rather than\ncontent, and both fixed at creation. Also when `_revision` is missing or is not a revision\nmarker.\n", + "description": "`IDENTIFIER_INVALID`, `ENTITY_TYPE_MISMATCH`.", "content": { "application/json": { "schema": { @@ -3845,8 +4169,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "No such variant under this schema, or it has no version at the instant addressed\n(`NOT_FOUND`). A variant whose versions are all still scheduled has none in effect, which is\nreported as such rather than as a missing variant.\n", + "description": "`ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`, `NO_ACTIVE_VERSION`, `VERSION_NOT_FOUND`.", "content": { "application/json": { "schema": { @@ -3856,7 +4190,7 @@ } }, "409": { - "description": "The version has been written since `_revision` was read (`WRITE_CONFLICT`, retryable after\nre-reading the version).\n", + "description": "`ENTITY_NOT_CONDITIONAL`.", "content": { "application/json": { "schema": { @@ -3867,10 +4201,10 @@ } } }, - "delete": { - "description": "Removes one variant of a conditional entity: the condition tuple it holds, its registration\nin the search index, and every version it accumulated.\n\nTwo phases. The first frees the tuple and deregisters the variant, and is what makes the\ncombination of condition values immediately reusable — the second removes the version rows in\nbatches afterwards. A response arrives only once both have finished for this request, but the\ntuple is reusable from the moment the first completes, whether or not the second did: a\nvariant with more versions than one transaction can carry is the ordinary case, not an edge\none. An interrupted delete is safe to send again; it picks up where it stopped.\n\nNothing is archived. A variant an order or contract pins stops resolving, and hydration drops\nthe reference leniently rather than failing the read.\n\nThis removes the **variant**, not one of its versions. To remove a single version, name it on\n`…/variants/{variant_id}/versions/{valid_from}` — including the one currently in effect, which\ndeliberately has no \"delete whichever is live\" shorthand: that is exactly the write nobody\nshould be able to ask for without saying which version they meant.\n", - "operationId": "$deleteConditionalVariant", - "summary": "$deleteConditionalVariant", + "put": { + "description": "Replaces the values of the version in effect. The body is the complete set of overrides: an\noverridable attribute absent from it stops being overridden, and one the variant may not\noverride keeps its stored value.\n\n`valid_from` and `conditions` are accepted only unchanged.\n", + "operationId": "$replaceActiveConditionalVariantVersion", + "summary": "$replaceActiveConditionalVariantVersion", "tags": [ "Conditional Pricing API" ], @@ -3898,7 +4232,7 @@ { "in": "path", "name": "variant_id", - "description": "The variant to remove", + "description": "The variant whose timeline this call addresses", "schema": { "type": "string" }, @@ -3906,19 +4240,29 @@ "example": "var-46045" } ], - "responses": { - "200": { - "description": "What the delete removed", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeletedVariant" - } + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReplaceVersionRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The version, as the write left it, together with anything the write moved", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WrittenVariantVersion" + } } } }, "400": { - "description": "Invalid request, e.g. the slug names no conditional entity type", + "description": "`VALID_FROM_IMMUTABLE`, `VALID_FROM_INVALID`, `VALUE_UNSTORABLE`, `IDENTIFIER_INVALID`,\n`ENTITY_TYPE_MISMATCH`.\n", "content": { "application/json": { "schema": { @@ -3927,8 +4271,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "This entity has no such variant (`NOT_FOUND`).", + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`, `NO_ACTIVE_VERSION`,\n`VERSION_NOT_FOUND`.\n", "content": { "application/json": { "schema": { @@ -3938,7 +4292,7 @@ } }, "409": { - "description": "The variant's items are being written concurrently (`WRITE_CONFLICT`, retryable).", + "description": "`WRITE_CONFLICT`, `VARIANT_CONDITIONS_IMMUTABLE`, `ENTITY_NOT_CONDITIONAL`.", "content": { "application/json": { "schema": { @@ -3948,13 +4302,11 @@ } } } - } - }, - "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions": { - "post": { - "description": "Appends a version to a variant: a new set of values taking effect at its own instant.\n\nThis is how a price changes. No version carries an end date and nothing is superseded\nexplicitly — the version in effect at an instant is simply the one with the latest `valid_from`\nat or before it, so appending a later version is the whole of \"this is the new price from then\non\". A version dated in the future is staged and excluded from resolution until its date.\n\n**A version is never refused for being late.** A `valid_from` in the past is written like any\nother and answered with warnings in `warnings` naming what it moved — what resolves now, what a\npast-dated read returns, or both. Correcting a price that took effect last week is ordinary\nwork; the alternative, deleting and recreating the variant, breaks every order and contract\npinning its id.\n\nWhat is refused is appending at a `valid_from` the variant already has: that write means either\n\"replace it\" or \"and also this\", and only the caller knows which. The two operations both\nexist, on the dated version path.\n\nThe variant's `conditions` are its identity and are fixed at creation; they may be sent back\nunchanged but never changed.\n", - "operationId": "$appendConditionalVariantVersion", - "summary": "$appendConditionalVariantVersion", + }, + "patch": { + "description": "Changes only the fields it names on the version in effect. `null` sets a value rather than\nremoving an override; use the replace operation to remove one.\n", + "operationId": "$patchActiveConditionalVariantVersion", + "summary": "$patchActiveConditionalVariantVersion", "tags": [ "Conditional Pricing API" ], @@ -3995,14 +4347,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AppendVersionRequest" + "$ref": "#/components/schemas/PatchVersionRequest" } } } }, "responses": { - "201": { - "description": "The version, as appended, together with anything the write moved", + "200": { + "description": "The version, as the write left it, together with anything the write moved", "content": { "application/json": { "schema": { @@ -4012,7 +4364,7 @@ } }, "400": { - "description": "The version cannot be appended as described: the body would change the variant's conditions,\nor `valid_from` is not a timestamp this store can sort by.\n", + "description": "`VALID_FROM_IMMUTABLE`, `VALID_FROM_INVALID`, `VALUE_UNSTORABLE`, `IDENTIFIER_INVALID`,\n`ENTITY_TYPE_MISMATCH`.\n", "content": { "application/json": { "schema": { @@ -4021,8 +4373,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "No such schema, or no such variant under it (`NOT_FOUND`).\n", + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`, `NO_ACTIVE_VERSION`,\n`VERSION_NOT_FOUND`.\n", "content": { "application/json": { "schema": { @@ -4032,7 +4394,7 @@ } }, "409": { - "description": "The variant already has a version at that `valid_from` (`VERSION_CONFLICT`) — append means\nappend, never an implicit overwrite. Replace or patch that version instead.\n", + "description": "`WRITE_CONFLICT`, `VARIANT_CONDITIONS_IMMUTABLE`, `ENTITY_NOT_CONDITIONAL`.", "content": { "application/json": { "schema": { @@ -4042,13 +4404,11 @@ } } } - } - }, - "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}": { - "get": { - "description": "Returns one specific version of a variant, by the instant it takes effect — what a form editing\nthat version loads.\n\nExact, never nearest: an instant the variant has no version at is a not-found rather than the\nversion that would be in effect at it. That question is the shorthand read's, or `:resolve`'s.\n", - "operationId": "$getConditionalVariantVersion", - "summary": "$getConditionalVariantVersion", + }, + "delete": { + "description": "Removes one variant: its condition tuple, its index entry and all its versions. The tuple\nbecomes reusable, and an interrupted delete is safe to send again.\n\nOrders and contracts pinning the variant stop resolving. To remove a single version, address\nit under `versions/{valid_from}`.\n", + "operationId": "$deleteConditionalVariant", + "summary": "$deleteConditionalVariant", "tags": [ "Conditional Pricing API" ], @@ -4076,37 +4436,27 @@ { "in": "path", "name": "variant_id", - "description": "The variant whose timeline this call addresses", + "description": "The variant to remove", "schema": { "type": "string" }, "required": true, "example": "var-46045" - }, - { - "in": "path", - "name": "valid_from", - "description": "The version to address, by the instant it takes effect.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time\n(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any accepted way: it is\ncanonicalized before it is matched, so the spelling a read returned and the spelling a\nhuman typed address the same version.\n", - "schema": { - "type": "string" - }, - "required": true, - "example": "2027-01-01T00:00:00.000Z" } ], "responses": { "200": { - "description": "The version, as stored", + "description": "What the delete removed", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VariantVersion" + "$ref": "#/components/schemas/DeletedVariant" } } } }, "400": { - "description": "Invalid request, e.g. a `valid_from` that is not a timestamp this store can sort by.\n", + "description": "`IDENTIFIER_INVALID`, `ENTITY_TYPE_MISMATCH`.", "content": { "application/json": { "schema": { @@ -4115,8 +4465,28 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "This variant has no version at that instant (`NOT_FOUND`).\n", + "description": "`ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } + }, + "409": { + "description": "`WRITE_CONFLICT`, `ENTITY_NOT_CONDITIONAL`.", "content": { "application/json": { "schema": { @@ -4126,11 +4496,13 @@ } } } - }, - "put": { - "description": "Replaces one version's values wholesale, addressed by its `valid_from`.\n\nEditable whatever its date, at both ends of the timeline: a scheduled version must stay\neditable so a staged price can be corrected before it goes live rather than accumulating dead\nversions beside it, and a past one must stay editable because correcting history is ordinary\nwork. Writing a superseded version is answered with a warning naming what a past-dated read now\nreturns; it is not refused.\n\nAttributes the variant may not override are ignored where the body carries them, and their\nstored value is preserved rather than dropped.\n", - "operationId": "$replaceConditionalVariantVersion", - "summary": "$replaceConditionalVariantVersion", + } + }, + "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions": { + "get": { + "description": "Lists one variant's versions. Cursor paging only: a page may be short or empty and still\ncarry a `next`, so page until `next` is absent. A cursor is bound to one variant and one\n`order`.\n", + "operationId": "$listConditionalVariantVersions", + "summary": "$listConditionalVariantVersions", "tags": [ "Conditional Pricing API" ], @@ -4158,7 +4530,7 @@ { "in": "path", "name": "variant_id", - "description": "The variant whose timeline this call addresses", + "description": "The variant whose timeline to list", "schema": { "type": "string" }, @@ -4166,39 +4538,105 @@ "example": "var-46045" }, { - "in": "path", - "name": "valid_from", - "description": "The version to address, by the instant it takes effect.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time\n(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any accepted way: it is\ncanonicalized before it is matched, so the spelling a read returned and the spelling a\nhuman typed address the same version.\n", + "in": "query", + "name": "limit", + "description": "Versions per page. Defaults to 100, which is also the maximum; a larger value is clamped.", + "schema": { + "type": "integer", + "minimum": 1, + "default": 100 + }, + "required": false, + "example": 100 + }, + { + "in": "query", + "name": "order", + "description": "Which end of the timeline to read from. Baked into every cursor this read issues.", + "schema": { + "type": "string", + "enum": [ + "asc", + "desc" + ], + "default": "asc" + }, + "required": false, + "example": "asc" + }, + { + "in": "query", + "name": "cursor", + "description": "Continue from a previous response's `next`. Opaque.", "schema": { "type": "string" }, - "required": true, - "example": "2027-01-01T00:00:00.000Z" + "required": false, + "example": "eyJzayI6IlYjcHJpY2Utc3AyNmQxeW8jdmFyLTQ2MDQ1IzIwMjYtMDEtMDFUMDA6MDA6MDAuMDAwWiIsIm9yZGVyIjoiYXNjIn0" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReplaceVersionRequest" - } - } - } - }, "responses": { "200": { - "description": "The version, as the write left it, together with anything the write moved", + "description": "A page of the variant's timeline, and the cursor that continues it", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WrittenVariantVersion" + "$ref": "#/components/schemas/VariantVersionList" + }, + "examples": { + "A short page that is not the last one": { + "summary": "One version and a `next` — a short page does not mean the timeline has ended", + "value": { + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2026-01-01T00:00:00.000Z", + "values": { + "unit_amount": 3261, + "unit_amount_decimal": "32.61" + }, + "_created_at": "2025-11-14T09:12:44.101Z", + "_updated_at": "2025-11-14T09:12:44.101Z" + } + ], + "next": "eyJzayI6IlYjcHJpY2Utc3AyNmQxeW8jdmFyLTQ2MDQ1IzIwMjYtMDEtMDFUMDA6MDA6MDAuMDAwWiIsIm9yZGVyIjoiYXNjIn0" + } + }, + "The last page": { + "summary": "No `next`, which is the end of the timeline", + "value": { + "results": [ + { + "variant_id": "var-46045", + "entity_id": "price-sp26d1yo", + "schema": "price", + "conditions": { + "postal_code": "46045", + "default": false + }, + "valid_from": "2027-01-01T00:00:00.000Z", + "values": { + "unit_amount": 3412, + "unit_amount_decimal": "34.12" + }, + "_created_at": "2026-08-02T16:40:03.882Z", + "_updated_at": "2026-08-02T16:40:03.882Z" + } + ] + } + } } } } }, "400": { - "description": "The write cannot be applied as described: it would move the version it addresses to another\n`valid_from`, or change the conditions its variant is pinned to — both identity rather than\ncontent, and both fixed at creation. Also when `_revision` is missing or is not a revision\nmarker.\n", + "description": "`CURSOR_INVALID`, `ENTITY_TYPE_MISMATCH`.", "content": { "application/json": { "schema": { @@ -4207,8 +4645,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "This variant has no version at that instant (`NOT_FOUND`).\n", + "description": "`ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`.", "content": { "application/json": { "schema": { @@ -4218,7 +4666,7 @@ } }, "409": { - "description": "The version has been written since `_revision` was read (`WRITE_CONFLICT`, retryable after\nre-reading the version).\n", + "description": "`ENTITY_NOT_CONDITIONAL`.", "content": { "application/json": { "schema": { @@ -4229,10 +4677,10 @@ } } }, - "patch": { - "description": "Changes only the fields it names on one version, addressed by its `valid_from`.\n\nEverything the body does not mention is left as stored. A partial update that tries to change a\npinned condition value is refused: condition values are immutable after a variant is created,\nand this is the path that rule is most likely to be broken on by accident.\n", - "operationId": "$patchConditionalVariantVersion", - "summary": "$patchConditionalVariantVersion", + "post": { + "description": "Appends a version taking effect at its own instant. The version in effect at any instant is\nthe one with the latest `valid_from` at or before it; a future one is staged until its date.\n\nA past `valid_from` is accepted and reported in `warnings`. One the variant already has is\nrefused — replace or patch that version instead.\n", + "operationId": "$appendConditionalVariantVersion", + "summary": "$appendConditionalVariantVersion", "tags": [ "Conditional Pricing API" ], @@ -4266,16 +4714,6 @@ }, "required": true, "example": "var-46045" - }, - { - "in": "path", - "name": "valid_from", - "description": "The version to address, by the instant it takes effect.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time\n(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any accepted way: it is\ncanonicalized before it is matched, so the spelling a read returned and the spelling a\nhuman typed address the same version.\n", - "schema": { - "type": "string" - }, - "required": true, - "example": "2027-01-01T00:00:00.000Z" } ], "requestBody": { @@ -4283,14 +4721,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PatchVersionRequest" + "$ref": "#/components/schemas/AppendVersionRequest" } } } }, "responses": { - "200": { - "description": "The version, as the write left it, together with anything the write moved", + "201": { + "description": "The version, as appended, together with anything the write moved", "content": { "application/json": { "schema": { @@ -4300,7 +4738,7 @@ } }, "400": { - "description": "The write cannot be applied as described: it would move the version it addresses to another\n`valid_from`, or change the conditions its variant is pinned to — both identity rather than\ncontent, and both fixed at creation. Also when `_revision` is missing or is not a revision\nmarker.\n", + "description": "`VALID_FROM_INVALID`, `VALUE_UNSTORABLE`, `IDENTIFIER_INVALID`, `ENTITY_TYPE_MISMATCH`.", "content": { "application/json": { "schema": { @@ -4309,8 +4747,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "This variant has no version at that instant (`NOT_FOUND`).\n", + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`.", "content": { "application/json": { "schema": { @@ -4320,7 +4768,7 @@ } }, "409": { - "description": "The version has been written since `_revision` was read (`WRITE_CONFLICT`, retryable after\nre-reading the version).\n", + "description": "`VERSION_CONFLICT`, `VARIANT_CONDITIONS_IMMUTABLE`, `ENTITY_NOT_CONDITIONAL`.", "content": { "application/json": { "schema": { @@ -4330,11 +4778,13 @@ } } } - }, - "delete": { - "description": "Removes one version of a variant.\n\nWithdrawing a scheduled adjustment is what this is for, and deleting a future version warns\nabout nothing — nothing that has resolved, or could have resolved, changes. Deleting a version\nthat has taken effect is allowed too and answered with a warning: it changes what a past-dated\nread returns, and if it was the version in effect it changes what resolves now.\n\n**A variant's last remaining version cannot be deleted.** Such a variant would still hold its\ncondition tuple and still be selectable, and then resolve to nothing — which is a variant delete\nwearing a version delete's clothes. Delete the variant instead; that frees the tuple too.\n\nThe variant itself is untouched: it keeps its conditions, its tuple and its place in the index.\n", - "operationId": "$deleteConditionalVariantVersion", - "summary": "$deleteConditionalVariantVersion", + } + }, + "/v1/conditional-pricing/{slug}/entities/{entity_id}/variants/{variant_id}/versions/{valid_from}": { + "get": { + "description": "Returns one version by the instant it takes effect. Exact, never nearest.", + "operationId": "$getConditionalVariantVersion", + "summary": "$getConditionalVariantVersion", "tags": [ "Conditional Pricing API" ], @@ -4372,38 +4822,27 @@ { "in": "path", "name": "valid_from", - "description": "The version to address, by the instant it takes effect.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time\n(`2026-01-01T00:00:00Z`), to at most millisecond precision. Written any accepted way: it is\ncanonicalized before it is matched, so the spelling a read returned and the spelling a\nhuman typed address the same version.\n", + "description": "The version to address, by the instant it takes effect. An RFC 3339 date\n(`2026-01-01`, read as midnight UTC) or date-time, to at most millisecond precision,\ncanonicalized before it is matched.\n", "schema": { "type": "string" }, "required": true, "example": "2027-01-01T00:00:00.000Z" - }, - { - "in": "query", - "name": "_revision", - "description": "The revision marker read from the version being deleted. The delete is refused if the\nversion has been written since.\n\nA query parameter rather than a body field, since a DELETE carrying a body travels badly\nthrough clients and proxies; it is the same marker the write bodies carry as `_revision`.\n", - "schema": { - "type": "integer", - "minimum": 1 - }, - "required": true, - "example": 3 } ], "responses": { "200": { - "description": "The version removed, together with anything the delete moved", + "description": "The version, as stored", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedVariantVersion" + "$ref": "#/components/schemas/VariantVersion" } } } }, "400": { - "description": "The version cannot be removed: it is the variant's only one, `_revision` is missing, or\n`valid_from` is not a timestamp this store can sort by.\n", + "description": "`VALID_FROM_INVALID`, `IDENTIFIER_INVALID`, `ENTITY_TYPE_MISMATCH`.", "content": { "application/json": { "schema": { @@ -4412,8 +4851,18 @@ } } }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "404": { - "description": "This variant has no version at that instant (`NOT_FOUND`).\n", + "description": "`ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`, `VERSION_NOT_FOUND`.", "content": { "application/json": { "schema": { @@ -4423,7 +4872,7 @@ } }, "409": { - "description": "The version has been written since `_revision` was read (`WRITE_CONFLICT`, retryable after\nre-reading the version).\n", + "description": "`ENTITY_NOT_CONDITIONAL`.", "content": { "application/json": { "schema": { @@ -4433,760 +4882,3628 @@ } } } - } - } - }, - "components": { - "securitySchemes": { - "EpilotAuth": { - "type": "http", - "scheme": "bearer", - "description": "Epilot Bearer Token" - }, - "EpilotPublicAuth": { - "type": "http", - "scheme": "bearer", - "description": "Epilot Public Access Bearer Token", - "bearerFormat": "JWT" - } - }, - "schemas": { - "IntegrationId": { - "type": "string", - "enum": [ - "getag", - "external-catalog" - ] }, - "ConditionalEntitySlug": { - "type": "string", - "description": "Schema slug of an entity type that can be conditional — the `{slug}` of every\nconditional-pricing route.\n", - "enum": [ - "product", - "price", - "coupon" - ] - }, - "ConditionType": { - "type": "string", - "description": "The kind of value a condition holds, which decides how a variant's pinned value is matched\nagainst a resolve context.\n\n- `string`: an arbitrary string, matched exactly and case-sensitively\n- `number`: a numeric value\n- `date`: a single date\n- `daterange`: a window with a from and an until timestamp; both ends may be left open\n- `boolean`: a true/false value\n- `select`: one of the values declared in `options`, unless `allow_any` is set\n- `location`: a geographic value, shaped by `format`\n\nThere is no condition type for the fallback variant. Being the entity's fallback is a\nproperty of the variant, set by the `default` flag on a variant write, and needs nothing\ndeclared in the schema.\n", - "enum": [ - "string", - "number", - "date", - "daterange", - "boolean", - "select", - "location" - ] - }, - "ConditionDefinition": { - "type": "object", - "description": "One condition dimension, in the shape a schema's `conditions` array holds it — copy it in\nverbatim.\n", - "required": [ - "name", - "label", - "type" + "put": { + "description": "Replaces one version's values, whatever its date. Attributes the variant may not override\nkeep their stored value. Writing a superseded version is reported in `warnings`.\n", + "operationId": "$replaceConditionalVariantVersion", + "summary": "$replaceConditionalVariantVersion", + "tags": [ + "Conditional Pricing API" ], - "properties": { - "name": { - "type": "string", - "description": "How variants and resolve contexts refer to this condition. Independent of attribute\nnames: a value needed as an attribute too is duplicated onto the variant.\n\n`default`, and any name beginning with `_`, are reserved for the server: a condition\ndeclared under one is ignored, since nothing could pin it and no context could address it.\n", - "example": "postal_code" - }, - "label": { - "type": "string", - "description": "Human-readable name of the condition.", - "example": "Postal Code" - }, - "type": { - "$ref": "#/components/schemas/ConditionType" + "parameters": [ + { + "in": "path", + "name": "slug", + "description": "The conditional entity type this variant belongs to", + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "required": true, + "example": "price" }, - "options": { - "type": "array", - "description": "The declared vocabulary of a `select` condition. Absent for every other type.\n\nThe same shape a `select` attribute's `options` has on the Entity API, item for item: an\nentry is either the value itself or an object carrying that value and an optional display\n`title`. A `title` is never pinned by a variant and never matched — two entries differing\nonly in their title are one vocabulary entry.\n\nEnforced on variant writes, unless `allow_any` is true: a pinned value outside the\nvocabulary is rejected with `CONDITION_VALUE_INVALID`. It is *not* enforced on resolve —\na vocabulary says what may be stored, not what may be asked for, so a context value\noutside it is a query that simply matches nothing.\n", - "items": { - "anyOf": [ - { - "type": "string", - "nullable": true - }, - { - "type": "object", - "required": [ - "value" - ], - "properties": { - "value": { - "type": "string" - }, - "title": { - "type": "string" - } - } - } - ] + { + "in": "path", + "name": "entity_id", + "description": "The conditional entity the variant belongs to", + "schema": { + "type": "string" }, - "example": [ - "private", - "commercial" - ] + "required": true, + "example": "price-sp26d1yo" }, - "allow_any": { - "type": "boolean", - "description": "Allow arbitrary stored values in addition to the declared `options`. Absent means strict:\na variant may only pin a declared option.\n", - "example": false + { + "in": "path", + "name": "variant_id", + "description": "The variant whose timeline this call addresses", + "schema": { + "type": "string" + }, + "required": true, + "example": "var-46045" }, - "format": { - "type": "string", - "description": "The value shape of a `location` condition. Absent for every other type.", - "enum": [ - "zipcode", - "zipcode + town" - ] + { + "in": "path", + "name": "valid_from", + "description": "The version to address, by the instant it takes effect. An RFC 3339 date\n(`2026-01-01`, read as midnight UTC) or date-time, to at most millisecond precision,\ncanonicalized before it is matched.\n", + "schema": { + "type": "string" + }, + "required": true, + "example": "2027-01-01T00:00:00.000Z" } - } - }, - "ConditionSet": { - "type": "object", - "description": "A named bundle of condition definitions, built in for one entity type.", - "required": [ - "id", - "label", - "description", - "conditions" ], - "properties": { - "id": { - "type": "string", - "description": "Identifies the set within this entity type's catalog.", - "example": "delivery_area" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReplaceVersionRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The version, as the write left it, together with anything the write moved", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WrittenVariantVersion" + } + } + } }, - "label": { - "type": "string", - "description": "Human-readable name of the set.", - "example": "Delivery Area" + "400": { + "description": "`VALID_FROM_IMMUTABLE`, `VALID_FROM_INVALID`, `VALUE_UNSTORABLE`, `IDENTIFIER_INVALID`,\n`ENTITY_TYPE_MISMATCH`.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } }, - "description": { - "type": "string", - "description": "What the set is for, and when to reach for it." + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } }, - "conditions": { - "type": "array", - "description": "The condition definitions to copy into the schema's own `conditions` array.", - "items": { - "$ref": "#/components/schemas/ConditionDefinition" + "404": { + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`, `VERSION_NOT_FOUND`.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } } - } - } - }, - "ConditionSetCatalog": { - "type": "object", - "required": [ - "results" - ], - "properties": { - "results": { - "type": "array", - "description": "The condition sets built in for the requested entity type, in the order they are offered.\n", - "items": { - "$ref": "#/components/schemas/ConditionSet" + }, + "409": { + "description": "`WRITE_CONFLICT`, `VARIANT_CONDITIONS_IMMUTABLE`, `ENTITY_NOT_CONDITIONAL`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } } } } }, - "ConditionalPricingErrorCode": { - "type": "string", - "description": "Machine-readable failure mode of a conditional-pricing operation, allowing clients\nto branch on the kind of failure instead of parsing the error message.\n\n- `NOT_FOUND` (404): the addressed entity, variant or version does not exist\n- `AMBIGUOUS_RESOLUTION` (409): several variants match the given context while a single result was requested\n- `TUPLE_CONFLICT` (409): the condition tuple is already claimed by another variant\n- `VERSION_CONFLICT` (409): a version already exists at the given `valid_from` on that variant\n- `CONDITION_UNDEFINED` (400): the context names a condition the entity's schema does not define\n- `OPERATOR_UNSUPPORTED` (400): the requested operator is not applicable to the condition's type\n- `CONTEXT_FORMAT_INVALID` (400): a context value is malformed for its condition type\n- `CONDITION_VALUE_INVALID` (400): a variant write pins a `select` value the condition's declared `options` do not contain\n- `TOO_MANY_MATCHES` (400): a multi-match resolve exceeded its result cap\n- `WRITE_CONFLICT` (409): transient write contention, retryable unlike `TUPLE_CONFLICT`\n\nEach code is emitted with the HTTP status shown above, and only with that status.\n", - "enum": [ - "NOT_FOUND", - "AMBIGUOUS_RESOLUTION", - "TUPLE_CONFLICT", - "VERSION_CONFLICT", - "CONDITION_UNDEFINED", - "OPERATOR_UNSUPPORTED", - "CONTEXT_FORMAT_INVALID", - "CONDITION_VALUE_INVALID", - "TOO_MANY_MATCHES", - "WRITE_CONFLICT" - ] - }, - "ResolveConditionalEntityRequest": { - "type": "object", - "additionalProperties": false, - "required": [ - "schema", - "entity_id" + "patch": { + "description": "Changes only the fields it names on one version.", + "operationId": "$patchConditionalVariantVersion", + "summary": "$patchConditionalVariantVersion", + "tags": [ + "Conditional Pricing API" ], - "properties": { - "schema": { - "$ref": "#/components/schemas/ConditionalEntitySlug" + "parameters": [ + { + "in": "path", + "name": "slug", + "description": "The conditional entity type this variant belongs to", + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "required": true, + "example": "price" }, - "entity_id": { - "type": "string", - "description": "The conditional entity to resolve. Resolution is always scoped to exactly one.", + { + "in": "path", + "name": "entity_id", + "description": "The conditional entity the variant belongs to", + "schema": { + "type": "string" + }, + "required": true, "example": "price-sp26d1yo" }, - "context": { - "$ref": "#/components/schemas/ResolveContext" - }, - "as_of": { - "type": "string", - "description": "The instant the version is selected at — the version with the latest `valid_from` at or\nbefore it. Defaults to now. A variant whose first version is later than this is\nscheduled rather than applicable, and is excluded from resolution entirely.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time\n(`2026-01-01T00:00:00Z`), to at most millisecond precision. Deliberately not declared as\n`format: date-time`, which would reject the plain-date form that this accepts.\n", - "example": "2027-03-15T00:00:00Z" - }, - "options": { - "$ref": "#/components/schemas/ResolveOptions" - } - } - }, - "ResolveContext": { - "type": "object", - "additionalProperties": true, - "description": "The situation to resolve for: a flat map keyed by condition name, as the entity's schema\ndeclares them. A condition left out of the map is not a wildcard — it matches only variants\nthat leave that condition unpinned.\n\nEach value is either an exact value, typed by its condition, or a single-operator predicate\nobject:\n\n- `{ \"lt\": v }`, `{ \"lte\": v }`, `{ \"gt\": v }`, `{ \"gte\": v }` — order against a `number` or\n `date` condition.\n- `{ \"in\": [...] }` — membership, against a `string`, `select` or `number` condition.\n- `{ \"between\": \"2026-03-01\" }` — the explicit spelling of `daterange` containment; a plain\n date supplied for a `daterange` condition means the same thing.\n- `{ \"exists\": true }` — pinned to any value. `{ \"exists\": false }` says what leaving the key\n out says.\n\nExact values are typed by their condition: a `string` or `select` matches exactly and\ncase-sensitively, with no trimming; a `location` of format `zipcode` is the postal code\nitself, and one of format `zipcode + town` an object carrying both, whose town is compared\ncase- and whitespace-insensitively while its postal code is not.\n\n`default`, and any name beginning with `_`, are reserved for the server and cannot be\nsupplied here.\n", - "example": { - "postal_code": "46045", - "consumption": { - "lt": 5000 - } - } - }, - "ResolveOptions": { - "type": "object", - "additionalProperties": false, - "properties": { - "resolve_one": { - "type": "boolean", - "default": false, - "description": "Ask for an unambiguous answer. Several applicable variants become `AMBIGUOUS_RESOLUTION`\nrather than a set, and nothing applicable becomes `NOT_FOUND` rather than an empty one.\nThe response shape does not change: `results` simply carries exactly one entry.\n" + { + "in": "path", + "name": "variant_id", + "description": "The variant whose timeline this call addresses", + "schema": { + "type": "string" + }, + "required": true, + "example": "var-46045" + }, + { + "in": "path", + "name": "valid_from", + "description": "The version to address, by the instant it takes effect. An RFC 3339 date\n(`2026-01-01`, read as midnight UTC) or date-time, to at most millisecond precision,\ncanonicalized before it is matched.\n", + "schema": { + "type": "string" + }, + "required": true, + "example": "2027-01-01T00:00:00.000Z" } - } - }, - "ResolvedVariants": { - "type": "object", - "required": [ - "results" ], - "properties": { - "results": { - "type": "array", - "description": "One composed payload per applicable variant, capped at 100 — a context selecting more\nthan that is answered with `TOO_MANY_MATCHES` instead, since each result costs its own\nversion lookup. No dominance or specificity ordering is applied between them.\n", - "items": { - "$ref": "#/components/schemas/ResolvedVariant" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PatchVersionRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The version, as the write left it, together with anything the write moved", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WrittenVariantVersion" + } + } + } + }, + "400": { + "description": "`VALID_FROM_IMMUTABLE`, `VALID_FROM_INVALID`, `VALUE_UNSTORABLE`, `IDENTIFIER_INVALID`,\n`ENTITY_TYPE_MISMATCH`.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } + }, + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "`SCHEMA_NOT_FOUND`, `ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`, `VERSION_NOT_FOUND`.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } + }, + "409": { + "description": "`WRITE_CONFLICT`, `VARIANT_CONDITIONS_IMMUTABLE`, `ENTITY_NOT_CONDITIONAL`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } } } } }, - "ResolvedVariant": { - "type": "object", - "additionalProperties": true, - "description": "The entity as this variant leaves it — every attribute of a plain entity read, with the\napplicable version's overrides applied — plus the discriminators saying where the numbers\ncame from.\n", - "required": [ - "_id", - "_variant_id", - "_version_valid_from", - "_conditions" + "delete": { + "description": "Removes one version. What the removal moves is reported in `warnings`. A variant's last\nremaining version cannot be removed — delete the variant instead.\n", + "operationId": "$deleteConditionalVariantVersion", + "summary": "$deleteConditionalVariantVersion", + "tags": [ + "Conditional Pricing API" ], - "properties": { - "_id": { - "type": "string", - "description": "The logical entity's id — the same one a plain entity read returns. Resolution never\nmints a new identity; a variant is a set of values for *this* entity, not another one.\n", + "parameters": [ + { + "in": "path", + "name": "slug", + "description": "The conditional entity type this variant belongs to", + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "required": true, + "example": "price" + }, + { + "in": "path", + "name": "entity_id", + "description": "The conditional entity the variant belongs to", + "schema": { + "type": "string" + }, + "required": true, "example": "price-sp26d1yo" }, - "_variant_id": { - "type": "string", - "description": "The variant these values came from. Durable: this is what an order or a contract pins to\nread the same numbers back later.\n", + { + "in": "path", + "name": "variant_id", + "description": "The variant whose timeline this call addresses", + "schema": { + "type": "string" + }, + "required": true, "example": "var-46045" }, - "_version_valid_from": { - "type": "string", - "description": "The `valid_from` of the version applied for the requested `as_of`.", + { + "in": "path", + "name": "valid_from", + "description": "The version to address, by the instant it takes effect. An RFC 3339 date\n(`2026-01-01`, read as midnight UTC) or date-time, to at most millisecond precision,\ncanonicalized before it is matched.\n", + "schema": { + "type": "string" + }, + "required": true, "example": "2027-01-01T00:00:00.000Z" }, - "_conditions": { - "allOf": [ - { - "$ref": "#/components/schemas/VariantConditions" - } - ], - "description": "The conditions this variant pins, plus the boolean `default` discriminator.\n\nUnderscore-prefixed, like every other discriminator here, so that it cannot collide with\nan attribute an organization happens to have called `conditions`.\n" + { + "in": "query", + "name": "_revision", + "description": "The revision read from the version being deleted. The delete is refused if the version\nhas been written since.\n", + "schema": { + "type": "integer", + "minimum": 1 + }, + "required": true, + "example": 3 } - } - }, - "CreateVariantRequest": { - "type": "object", - "additionalProperties": false, - "required": [ - "values" ], - "properties": { - "conditions": { - "$ref": "#/components/schemas/PinnedConditions" + "responses": { + "200": { + "description": "The version removed, together with anything the delete moved", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeletedVariantVersion" + } + } + } }, - "default": { - "type": "boolean", - "default": false, - "description": "Mark this variant as the entity's fallback: the one served when no other variant applies.\n\nA property of the variant, never an entry in `conditions` — a variant claiming a value for\nthe marker would hold a real condition tuple while being permanently unmatchable, since no\nresolve context ever supplies it. A default variant cannot pin anything else, and an\nentity can have at most one.\n\nAvailable to every conditional entity: nothing has to be declared in the schema first.\nThe variant is stored pinning one reserved condition, which is what makes the ordinary\ncondition-tuple guard enforce at-most-one-per-entity with no rule of its own.\n" + "400": { + "description": "`VALID_FROM_INVALID`, `IDENTIFIER_INVALID`, `ENTITY_TYPE_MISMATCH`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } }, - "valid_from": { - "type": "string", - "description": "When the first version takes effect. Defaults to now.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time\n(`2026-01-01T00:00:00Z`), to at most millisecond precision. Deliberately not declared as\n`format: date-time`, which would reject the plain-date form that this accepts.\n", - "example": "2027-01-01T00:00:00Z" + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } }, - "values": { - "$ref": "#/components/schemas/VariantValues" + "404": { + "description": "`ENTITY_NOT_FOUND`, `VARIANT_NOT_FOUND`, `VERSION_NOT_FOUND`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } + }, + "409": { + "description": "`LAST_VERSION_UNDELETABLE`, `WRITE_CONFLICT`, `ENTITY_NOT_CONDITIONAL`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } } } - }, - "VariantConditions": { - "type": "object", - "additionalProperties": true, - "required": [ - "default" + } + }, + "/v1/conditional-pricing/{slug}/variants:batchUpsert": { + "post": { + "description": "Writes up to 100 variants or versions in one call. Each item names its own entity, so one\ncall can span a tariff hierarchy, and addresses a variant by condition tuple rather than by\nid — the id it created or found is on the result entry.\n\nEach item's outcome is derived from what is stored: an unknown tuple is `variant_created`, a\nknown tuple with no version at the item's `valid_from` is `version_created`, an existing\nversion there is `updated`, and a write matching what is stored is `skipped`. An item\nwithout `valid_from` is a last-write-wins write with no `skipped` detection.\n\nItems addressing the same `(entity_id, conditions)` apply in array order; the rest run in\nparallel. No cross-item rollback, and no `_revision` guard.\n", + "operationId": "$batchUpsertConditionalVariants", + "summary": "$batchUpsertConditionalVariants", + "tags": [ + "Conditional Pricing API" ], - "description": "A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a\nboolean `default` saying whether this is the entity's fallback.\n\n`default` is always present and always a boolean, so a client can branch on \"did I get the\nfallback?\" without knowing how one is stored. The reserved condition a fallback is actually\npinned under never appears here.\n", - "properties": { - "default": { - "type": "boolean" - } - }, - "example": { - "postal_code": "46045", - "default": false - } - }, - "PinnedConditions": { - "type": "object", - "additionalProperties": true, - "description": "The situation this variant applies to: a flat map keyed by condition name, as the entity's\nschema declares them. A condition left out is a wildcard — the variant applies whatever the\ncontext says for it, which is what makes adding a condition to a schema non-breaking for the\nvariants that already exist.\n\nExact values only. Predicates are accepted in a resolve context and nowhere else, so that\nmatching is decided in exactly one place.\n\nValues are typed by their condition and stored canonicalized for that type: a `date` becomes\nmillisecond-precision UTC, a `daterange` an object carrying `from` and `until` where an empty\nstring is an open end, a `location` of format `zipcode` the postal code itself and one of\nformat `zipcode + town` an object carrying both. A `select` value must be a string, and must\nbe one the condition's `options` declare unless it sets `allow_any`.\n\n`default`, and any name beginning with `_`, are reserved for the server and cannot be pinned\nhere. Whether a variant is the entity's fallback is set through the request's `default` flag.\n", - "example": { - "postal_code": "46045" - } - }, - "VariantValues": { - "type": "object", - "additionalProperties": true, - "description": "The attribute values this version overrides on the base entity, keyed by attribute name.\n\nOnly attributes currently declaring `overridable_attribute` are applied. Metadata fields\n(anything underscore-prefixed), readonly attributes, hidden attributes and non-overridable\nattributes present here are ignored rather than rejected, so a client working from a slightly\nstale schema snapshot still succeeds instead of failing on fields it could not have known to\ndrop. An attribute's `render_condition` says when to show it and has no bearing on whether a\nvariant may override it.\n\nIgnored means *not updated*, never *removed*: a value already stored for an attribute that is\nnot currently overridable is preserved, so removing and restoring the flag deactivates and\nthen reactivates the same override.\n\nA composite price's `price_components` is an ordinary overridable relation attribute: a\ncomposite variant pins its component variants here the same way any other relation value is\nset, with no special handling.\n", - "example": { - "unit_amount": 2499, - "unit_amount_decimal": "24.99" - } - }, - "CreatedVariant": { - "type": "object", - "required": [ - "variant_id", - "entity_id", - "schema", - "conditions", - "valid_from", - "values", - "_created_at", - "_updated_at", - "_revision", - "warnings" + "parameters": [ + { + "in": "path", + "name": "slug", + "description": "The conditional entity type every item in this call writes under", + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "required": true, + "example": "price" + } ], - "properties": { - "variant_id": { - "type": "string", - "description": "Server-generated, always. This is the durable key orders and contracts pin, so it is never\naccepted from a client — a client-suppliable id would risk collisions between independent\nimporters.\n", - "example": "var-46045" - }, - "entity_id": { - "type": "string", - "example": "price-sp26d1yo" - }, - "schema": { - "$ref": "#/components/schemas/ConditionalEntitySlug" - }, - "conditions": { - "allOf": [ - { - "$ref": "#/components/schemas/VariantConditions" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BatchUpsertVariantsRequest" + }, + "examples": { + "A monthly refresh cycle": { + "summary": "Five items across two entities — a new postal code, a scheduled adjustment, a correction, an unchanged row and one bad source row", + "value": { + "correlation_id": "tariff-refresh-2027-01", + "items": [ + { + "entity_id": "price-sp26d1yo", + "conditions": { + "postal_code": "46045" + }, + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 3261, + "unit_amount_decimal": "32.61" + } + }, + { + "entity_id": "price-sp26d1yo", + "conditions": { + "postal_code": "50667" + }, + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 3412, + "unit_amount_decimal": "34.12" + } + }, + { + "entity_id": "price-base-fee", + "conditions": { + "postal_code": "50667" + }, + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 1290, + "unit_amount_decimal": "12.90" + } + }, + { + "entity_id": "price-sp26d1yo", + "conditions": { + "postal_code": "80331" + }, + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 3120, + "unit_amount_decimal": "31.20", + "description": "Grundpreis 2027" + } + }, + { + "entity_id": "price-sp26d1yo", + "conditions": { + "postal_code": "10115", + "segment": "industrial" + }, + "valid_from": "2027-01-01T00:00:00Z", + "values": { + "unit_amount": 2980, + "unit_amount_decimal": "29.80" + } + } + ] + } + } } - ], - "description": "The situation this variant applies to, plus the boolean `default` discriminator — the\nsame shape `_conditions` has on a resolved payload.\n" - }, - "valid_from": { - "type": "string", - "description": "When the first version takes effect, canonicalized to millisecond-precision UTC.", - "example": "2027-01-01T00:00:00.000Z" - }, - "values": { - "$ref": "#/components/schemas/VariantValues" - }, - "_created_at": { - "type": "string", - "description": "When the first version was created.", - "readOnly": true - }, - "_updated_at": { - "type": "string", - "description": "When the first version was last written.", - "readOnly": true - }, - "_revision": { - "type": "number", - "description": "The revision a later write to this version must carry to be accepted. Genuinely current,\nunlike one read back later from an eventually-consistent read.\n", - "readOnly": true - }, - "warnings": { - "type": "array", - "description": "Things worth knowing that did not stop the write. Empty in the ordinary case — a client\nreads its length rather than branching on its absence.\n", - "items": { - "$ref": "#/components/schemas/VariantWriteWarning" } } - } - }, - "VariantWriteWarning": { - "type": "object", - "required": [ - "code", - "message", - "variant_count", - "cap" - ], - "properties": { - "code": { - "type": "string", - "description": "- `VARIANT_COUNT_APPROACHING_CAP`: this entity is nearing the number of variants it may\n hold. Surfaced rather than rejected, so an importer finds out with a whole run's notice\n instead of discovering the limit halfway through a refresh.\n", - "enum": [ - "VARIANT_COUNT_APPROACHING_CAP" - ] + }, + "responses": { + "200": { + "description": "What every item did, in request order, and a count per outcome. Always `200`, whatever\nthe per-item outcomes.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BatchUpsertResult" + }, + "examples": { + "Every outcome once": { + "summary": "The five items above, in order", + "value": { + "correlation_id": "tariff-refresh-2027-01", + "counts": { + "variant_created": 1, + "version_created": 1, + "updated": 1, + "skipped": 1, + "error": 1 + }, + "results": [ + { + "outcome": "variant_created", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "valid_from": "2027-01-01T00:00:00.000Z", + "warnings": [ + { + "code": "VARIANT_COUNT_APPROACHING_CAP", + "message": "This entity holds 4998 of the 5000 variants it may hold", + "details": { + "variant_count": 4998, + "cap": 5000 + } + } + ] + }, + { + "outcome": "version_created", + "entity_id": "price-sp26d1yo", + "variant_id": "var-50667", + "valid_from": "2027-01-01T00:00:00.000Z", + "warnings": [] + }, + { + "outcome": "updated", + "entity_id": "price-base-fee", + "variant_id": "var-bf-50667", + "valid_from": "2027-01-01T00:00:00.000Z", + "warnings": [] + }, + { + "outcome": "skipped", + "entity_id": "price-sp26d1yo", + "variant_id": "var-80331", + "valid_from": "2027-01-01T00:00:00.000Z", + "warnings": [ + { + "code": "ATTRIBUTES_NOT_APPLIED", + "message": "The value sent for description was not applied", + "details": { + "attributes": [ + { + "attribute": "description", + "reason": "ATTRIBUTE_NOT_OVERRIDABLE" + } + ] + } + } + ] + }, + { + "outcome": "error", + "entity_id": "price-sp26d1yo", + "warnings": [], + "error": { + "message": "The value pinned for condition segment is not one of its declared options", + "code": "CONDITION_VALUE_INVALID", + "details": { + "condition_name": "segment", + "value": "industrial", + "options": [ + "private", + "commercial" + ] + } + } + } + ] + } + } + } + } + } }, - "message": { - "type": "string" + "400": { + "description": "The envelope cannot be processed: more than 100 items, an empty `items`, a slug that\nnames no conditional entity type, or a body this schema rejects. No `code` is carried —\nan individual item's failure is on its own result entry.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } }, - "variant_count": { - "type": "number", - "description": "Variants this entity holds, including the one just created." + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } }, - "cap": { - "type": "number", - "description": "Variants this entity may hold. Configurable per organization." + "404": { + "description": "`SCHEMA_NOT_FOUND`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } } } - }, - "DeletedVariant": { - "type": "object", - "required": [ - "variant_id", - "entity_id", - "schema", - "tuple_released", - "versions_deleted" + } + }, + "/v1/conditional-pricing/{slug}/variants:batchDelete": { + "post": { + "description": "Removes up to 100 variants or versions in one call. An item carrying `valid_from` removes\nthat version; one without it removes the whole variant.\n\nEach item addresses its variant by `variant_id` beside its `entity_id`, or by the condition\ntuple it pins, never both. Use ids once a condition has left the schema, since its tuple can\nno longer be canonicalized.\n\nItems addressing the same variant apply in array order, resolved to ids first; the rest run\nin parallel. An item addressing a missing variant or version is `skipped`, and the call is\nsafe to send again.\n", + "operationId": "$batchDeleteConditionalVariants", + "summary": "$batchDeleteConditionalVariants", + "tags": [ + "Conditional Pricing API" ], - "properties": { - "variant_id": { - "type": "string", - "example": "var-46045" - }, - "entity_id": { - "type": "string", - "example": "price-sp26d1yo" - }, - "schema": { - "$ref": "#/components/schemas/ConditionalEntitySlug" - }, - "tuple_released": { - "type": "boolean", - "description": "Whether this call is the one that freed the variant's combination of condition values.\n`false` where an earlier, interrupted attempt had already freed it — the delete still\nsucceeded, and the combination was already reusable.\n" - }, - "versions_deleted": { - "type": "number", - "description": "Version rows this call removed." + "parameters": [ + { + "in": "path", + "name": "slug", + "description": "The conditional entity type every item in this call removes from", + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "required": true, + "example": "price" } - } - }, - "VariantVersion": { - "type": "object", - "description": "One version of one variant: the attribute overrides it carries, the instant it takes effect,\nand the variant it belongs to.\n\nThese are the version's **own** overrides, not the base entity overlaid with them — this is\nwhat an editing screen loads and saves, and what it edits is the overrides. Composing them onto\nthe entity is what `:resolve` answers.\n", - "required": [ - "variant_id", - "entity_id", - "schema", - "conditions", - "valid_from", - "values", - "_created_at", - "_updated_at", - "_revision" ], - "properties": { - "variant_id": { - "type": "string", - "example": "var-46045" - }, - "entity_id": { - "type": "string", - "example": "price-sp26d1yo" - }, - "schema": { - "$ref": "#/components/schemas/ConditionalEntitySlug" - }, - "conditions": { - "allOf": [ - { - "$ref": "#/components/schemas/VariantConditions" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BatchDeleteVariantsRequest" + }, + "examples": { + "A cleanup pass, addressed both ways": { + "summary": "A version withdrawn by the tuple that pins it, a whole variant removed by id, and a version delete that would leave its variant with none", + "value": { + "correlation_id": "postal-code-cleanup-2026-09", + "items": [ + { + "entity_id": "price-sp26d1yo", + "conditions": { + "postal_code": "46045" + }, + "valid_from": "2026-01-01T00:00:00Z" + }, + { + "entity_id": "price-sp26d1yo", + "conditions": { + "postal_code": "99998" + } + }, + { + "entity_id": "price-sp26d1yo", + "variant_id": "var-80331", + "valid_from": "2026-01-01T00:00:00Z" + } + ] + } + } } - ], - "description": "The situation the variant applies to, plus the boolean `default` discriminator. A property\nof the variant rather than of this version: every version of a variant carries the same\none, and no version write can change it.\n" - }, - "valid_from": { - "type": "string", - "description": "When this version takes effect, canonicalized to millisecond-precision UTC. A version's\nidentity within its variant — it never moves.\n", - "example": "2027-01-01T00:00:00.000Z" - }, - "values": { - "$ref": "#/components/schemas/VariantValues" - }, - "_created_at": { - "type": "string", - "description": "When this version was created.", - "readOnly": true + } + } + }, + "responses": { + "200": { + "description": "What every item did, in request order, and a count per outcome. Always `200`, whatever\nthe per-item outcomes.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BatchDeleteResult" + }, + "examples": { + "Every outcome once": { + "summary": "The three items above, in order — the second addressed a tuple no variant pins", + "value": { + "correlation_id": "postal-code-cleanup-2026-09", + "counts": { + "deleted": 1, + "skipped": 1, + "error": 1 + }, + "results": [ + { + "outcome": "deleted", + "entity_id": "price-sp26d1yo", + "variant_id": "var-46045", + "valid_from": "2026-01-01T00:00:00.000Z", + "warnings": [ + { + "code": "ACTIVE_VERSION_CHANGED", + "message": "The version in effect was removed, so what resolves now has changed", + "details": { + "valid_from": "2026-01-01T00:00:00.000Z", + "active_valid_from": "2026-01-01T00:00:00.000Z" + } + } + ] + }, + { + "outcome": "skipped", + "entity_id": "price-sp26d1yo", + "warnings": [] + }, + { + "outcome": "error", + "entity_id": "price-sp26d1yo", + "variant_id": "var-80331", + "valid_from": "2026-01-01T00:00:00.000Z", + "warnings": [], + "error": { + "message": "var-80331 has only this version, so removing it would leave the variant unresolvable", + "code": "LAST_VERSION_UNDELETABLE", + "details": { + "variant_id": "var-80331", + "valid_from": "2026-01-01T00:00:00.000Z" + } + } + } + ] + } + } + } + } + } }, - "_updated_at": { - "type": "string", - "description": "When this version was last written.", - "readOnly": true + "400": { + "description": "The envelope cannot be processed: more than 100 items, an empty `items`, a slug that\nnames no conditional entity type, an item naming both a `variant_id` and a condition\ntuple, or a body this schema rejects. No `code` is carried — an individual item's\nfailure is on its own result entry.\n", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" + } + } + } }, - "_revision": { - "type": "integer", - "description": "The revision a write to this version must carry to be accepted. Always current: every read\nthat returns one is strongly consistent, so it is never a marker a write would be refused\nfor having read too early.\n", - "readOnly": true, - "example": 3 - } - } - }, - "WrittenVariantVersion": { - "description": "A version as a write left it, together with anything the write moved.\n", - "allOf": [ - { - "$ref": "#/components/schemas/VariantVersion" + "403": { + "description": "The token names no organization this API can act for", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } }, - { - "type": "object", - "required": [ - "warnings" - ], - "properties": { - "warnings": { - "type": "array", - "description": "What this write moved, if anything. Empty in the ordinary case — a client reads its\nlength rather than branching on its absence.\n", - "items": { - "$ref": "#/components/schemas/VersionWriteWarning" + "404": { + "description": "`SCHEMA_NOT_FOUND`.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ConditionalPricingError" } } } } + } + } + } + }, + "components": { + "securitySchemes": { + "EpilotAuth": { + "type": "http", + "scheme": "bearer", + "description": "Epilot Bearer Token" + }, + "EpilotPublicAuth": { + "type": "http", + "scheme": "bearer", + "description": "Epilot Public Access Bearer Token", + "bearerFormat": "JWT" + } + }, + "schemas": { + "IntegrationId": { + "type": "string", + "enum": [ + "getag", + "external-catalog" ] }, - "DeletedVariantVersion": { + "ConditionalEntitySlug": { + "type": "string", + "description": "Schema slug of an entity type that can be conditional — the `{slug}` of every conditional-pricing route.", + "enum": [ + "product", + "price", + "coupon" + ] + }, + "ConditionType": { + "type": "string", + "description": "The kind of value a condition holds, which decides how a pinned value is matched against a\nresolve context.\n\n- `string`: an arbitrary string, matched exactly and case-sensitively\n- `number`: a numeric value\n- `date`: a single date\n- `daterange`: a window with a from and an until timestamp; either end may be left open\n- `boolean`: a true/false value\n- `select`: one of the values declared in `options`, which is always a closed vocabulary\n- `location`: a geographic value, shaped by `format`\n", + "enum": [ + "string", + "number", + "date", + "daterange", + "boolean", + "select", + "location" + ] + }, + "ConditionDefinition": { "type": "object", + "description": "One condition dimension, in the shape a schema's `conditions` array holds it — copy it in verbatim.", "required": [ - "variant_id", - "entity_id", - "schema", - "valid_from", - "warnings" + "id", + "name", + "label", + "type" ], "properties": { - "variant_id": { + "id": { "type": "string", - "example": "var-46045" + "format": "uuid", + "description": "Stable identity of the condition, supplied on creation and round-tripped unchanged. A\ncatalog condition keeps the id the catalog gives it.\n", + "example": "d5839b94-ba20-4225-a78e-76951d352bd6" }, - "entity_id": { + "name": { "type": "string", - "example": "price-sp26d1yo" - }, - "schema": { - "$ref": "#/components/schemas/ConditionalEntitySlug" + "description": "How variants and resolve contexts refer to this condition, independent of attribute\nnames. `default` and names beginning with `_` are reserved and are ignored here.\n", + "example": "postal_code" }, - "valid_from": { + "label": { "type": "string", - "description": "The version removed, canonicalized to millisecond-precision UTC.", - "example": "2027-01-01T00:00:00.000Z" + "description": "Human-readable name of the condition.", + "example": "Postal Code" }, - "warnings": { + "type": { + "$ref": "#/components/schemas/ConditionType" + }, + "options": { "type": "array", - "description": "What the delete moved, if anything. Empty when a scheduled version was withdrawn.", + "description": "The vocabulary of a `select` condition, absent for every other type. Each entry is the\nvalue itself or an object carrying that value and a display `title`, which is never\nmatched.\n\nAlways closed: a pinned value outside it is `CONDITION_VALUE_INVALID`, and while\n`options` is absent or empty the condition admits no pin at all. Not enforced on\nresolve, where a context value outside the vocabulary matches nothing.\n", "items": { - "$ref": "#/components/schemas/VersionWriteWarning" - } - } - } - }, - "VersionWriteWarning": { - "type": "object", - "description": "Something a version write moved. A version write is never refused for being late — backdating a\nversion, and editing or deleting one that has already been superseded, are both accepted — so\nwhat a caller gets instead is a warning naming exactly what changed. One write can carry both\ncodes.\n", - "required": [ - "code", - "message", - "valid_from" - ], - "properties": { - "code": { - "type": "string", - "description": "- `ACTIVE_VERSION_REPLACED`: what resolves **now** changed, other than by a newer version\n taking effect. The version in effect was written behind, or removed.\n- `SUPERSEDED_VERSION_WRITTEN`: what a past-dated (`as_of`) read returns changed. The write\n landed on, or created, a version that is not the one currently in effect.\n", - "enum": [ - "ACTIVE_VERSION_REPLACED", - "SUPERSEDED_VERSION_WRITTEN" + "anyOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "string" + }, + "title": { + "type": "string" + } + } + } + ] + }, + "example": [ + "private", + { + "value": "commercial", + "title": "Commercial customers" + } ] }, - "message": { - "type": "string" - }, - "valid_from": { - "type": "string", - "description": "The version this write created, changed or removed.", - "example": "2026-08-01T00:00:00.000Z" - }, - "active_valid_from": { + "format": { "type": "string", - "description": "The version in effect when the write landed, before it did. Absent when the variant had\nnone — every version of it still scheduled.\n", - "example": "2026-01-01T00:00:00.000Z" + "description": "The value shape of a `location` condition. Absent for every other type.", + "enum": [ + "zipcode", + "zipcode_town" + ] } } }, - "AppendVersionRequest": { + "ConditionSet": { "type": "object", - "additionalProperties": false, + "description": "A named bundle of condition definitions, built in for one entity type.", "required": [ - "values" + "id", + "label", + "description", + "conditions" ], "properties": { - "valid_from": { + "id": { "type": "string", - "description": "When this version takes effect. Defaults to now.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time\n(`2026-01-01T00:00:00Z`), to at most millisecond precision. Deliberately not declared as\n`format: date-time`, which would reject the plain-date form that this accepts.\n\nA date in the past is accepted and answered with warnings, never refused. A date the\nvariant already has a version at is refused as `VERSION_CONFLICT`.\n\n**Omit this to mean \"now\"** — that is the only spelling of now that is reliably silent. A\ntimestamp taken from the caller's own clock is already some milliseconds old when the\nserver judges it, which makes it a backdate, however small, and it is answered with the\nwarnings a backdate earns.\n", - "example": "2027-01-01T00:00:00Z" + "description": "Identifies the set within this entity type's catalog.", + "example": "delivery_area" }, - "values": { - "$ref": "#/components/schemas/VariantValues" + "label": { + "type": "string", + "description": "Human-readable name of the set.", + "example": "Delivery Area" + }, + "description": { + "type": "string", + "description": "What the set is for, and when to reach for it." }, "conditions": { + "type": "array", + "description": "The condition definitions to copy into the schema's own `conditions` array.", + "items": { + "$ref": "#/components/schemas/ConditionDefinition" + } + } + } + }, + "ConditionSetCatalog": { + "type": "object", + "required": [ + "results" + ], + "properties": { + "results": { + "type": "array", + "description": "The condition sets built in for the requested entity type, in the order they are offered.", + "items": { + "$ref": "#/components/schemas/ConditionSet" + } + } + } + }, + "ConditionalPricingErrorCode": { + "type": "string", + "description": "Machine-readable failure mode of a conditional-pricing operation, so a client can branch on\nthe kind of failure instead of parsing the message. A `400` is about the request; a `409` is\nabout what is already stored. Refusals raised by request validation carry no `code` at all.\n\n- `SCHEMA_NOT_FOUND` (404): no conditional entity type by that slug\n- `ENTITY_NOT_FOUND` (404): the schema holds no entity with that id\n- `ENTITY_TYPE_MISMATCH` (400): that id belongs to an entity of another type than the slug named\n- `ENTITY_NOT_CONDITIONAL` (409): the entity is of the right type but was not created as a conditional one\n- `VARIANT_NOT_FOUND` (404): the entity has no such variant\n- `VERSION_NOT_FOUND` (404): the variant has no version at that `valid_from`\n- `NO_MATCHES` (404): nothing applied to the context and the entity has no `default` variant\n- `NO_ACTIVE_VERSION` (404): the variant has no version in effect at the instant asked about\n- `AMBIGUOUS_RESOLUTION` (409): several variants match the given context while a single result was requested\n- `TUPLE_CONFLICT` (409): the condition tuple is already claimed by another variant\n- `VERSION_CONFLICT` (409): a version already exists at the given `valid_from` on that variant\n- `CONDITION_UNDEFINED` (400): the request names a condition the entity's schema does not define\n- `VARIANT_PIN_UNDECLARED` (409): a variant a resolve would compose pins a condition the entity's schema no longer declares\n- `OPERATOR_UNSUPPORTED` (400): the requested predicate, or a sort, is not applicable to the condition's type\n- `CONTEXT_FORMAT_INVALID` (400): a resolve context or listing filter value is malformed for its condition type\n- `CONDITION_VALUE_INVALID` (400): a variant write pins a `select` value absent from the condition's declared `options`\n- `CONDITION_UNCONFIGURED` (409): a variant write pins a `select` condition whose `options` are absent or empty\n- `TOO_MANY_MATCHES` (400): a multi-match resolve exceeded its result cap\n- `WRITE_CONFLICT` (409): transient write contention, retryable unlike `TUPLE_CONFLICT`\n- `OFFSET_WINDOW_EXCEEDED` (400): a listing's `from` plus `size` reaches past the offset window the search index allows\n- `CURSOR_INVALID` (400): a paging cursor cannot be read, or does not belong to the read it was sent with\n- `VARIANT_LIMIT_REACHED` (409): the entity already holds every variant it may hold\n- `PIN_FORMAT_INVALID` (400): a variant pins a value malformed for its condition's type\n- `VARIANT_UNPINNED` (400): a variant write pins no condition and is not marked `default`, or a batch delete item addresses no variant\n- `LAST_VERSION_UNDELETABLE` (409): the delete would leave the variant with no version at all\n- `CONDITION_UNREADABLE` (409): the entity's schema declares a condition in a way this deploy cannot read\n- `SORT_INVALID` (400): a listing's `sort` is not `conditions.:asc` or `conditions.:desc`\n- `DEFAULT_MARKER_RESERVED` (400): a variant write's pins, or a resolve context, address the fallback marker — `default` or `_default`\n- `DEFAULT_VARIANT_PINS_CONDITIONS` (400): a variant marked `default` also pins real conditions\n- `VALID_FROM_IMMUTABLE` (400): a version write asks for a different `valid_from` than the version its own address names\n- `VARIANT_CONDITIONS_IMMUTABLE` (409): a version write carries a condition tuple other than the one its variant was created with\n- `IDENTIFIER_INVALID` (400): an id in the request cannot be used as a storage key — empty, carrying an unsupported character, or longer than 128 characters\n- `VALID_FROM_INVALID` (400): a `valid_from` is not one of the timestamp forms a version timeline can be sorted by\n- `VALUE_UNSTORABLE` (400): a write carries a value the store cannot hold, such as a non-finite number or one outside the table's numeric range\n", + "enum": [ + "SCHEMA_NOT_FOUND", + "ENTITY_NOT_FOUND", + "ENTITY_TYPE_MISMATCH", + "ENTITY_NOT_CONDITIONAL", + "VARIANT_NOT_FOUND", + "VERSION_NOT_FOUND", + "NO_MATCHES", + "NO_ACTIVE_VERSION", + "AMBIGUOUS_RESOLUTION", + "TUPLE_CONFLICT", + "VERSION_CONFLICT", + "CONDITION_UNDEFINED", + "VARIANT_PIN_UNDECLARED", + "OPERATOR_UNSUPPORTED", + "CONTEXT_FORMAT_INVALID", + "CONDITION_VALUE_INVALID", + "CONDITION_UNCONFIGURED", + "TOO_MANY_MATCHES", + "WRITE_CONFLICT", + "OFFSET_WINDOW_EXCEEDED", + "CURSOR_INVALID", + "VARIANT_LIMIT_REACHED", + "PIN_FORMAT_INVALID", + "VARIANT_UNPINNED", + "LAST_VERSION_UNDELETABLE", + "CONDITION_UNREADABLE", + "SORT_INVALID", + "DEFAULT_MARKER_RESERVED", + "DEFAULT_VARIANT_PINS_CONDITIONS", + "VALID_FROM_IMMUTABLE", + "VARIANT_CONDITIONS_IMMUTABLE", + "IDENTIFIER_INVALID", + "VALID_FROM_INVALID", + "VALUE_UNSTORABLE" + ] + }, + "ResolveConditionalEntityRequest": { + "description": "A resolve names one conditional entity and selects its variants either by `context` or by\n`variant_id`, never both. `context: {}` matches nothing and so returns the `default`\nvariant, which is how to ask for it without knowing its id.\n", + "oneOf": [ + { + "$ref": "#/components/schemas/ResolveByContextRequest" + }, + { + "$ref": "#/components/schemas/ResolveByPinRequest" + } + ] + }, + "ResolveByContextRequest": { + "type": "object", + "additionalProperties": false, + "description": "Resolve by matching a situation: which of this entity's variants apply to `context`, each\ncomposed with the version in effect at `as_of`.\n", + "required": [ + "schema", + "entity_id", + "context" + ], + "properties": { + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "entity_id": { + "type": "string", + "description": "The conditional entity to resolve. Resolution is always scoped to exactly one.", + "example": "price-sp26d1yo" + }, + "context": { + "$ref": "#/components/schemas/ResolveContext" + }, + "as_of": { + "type": "string", + "description": "The instant the version is selected at — the version with the latest `valid_from` at or\nbefore it. Defaults to now. A variant whose first version is later is excluded from\nmatching; a pin naming one is answered `NO_ACTIVE_VERSION` instead.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most\nmillisecond precision.\n", + "example": "2027-03-15T00:00:00Z" + }, + "options": { + "$ref": "#/components/schemas/ResolveOptions" + } + } + }, + "ResolveByPinRequest": { + "type": "object", + "additionalProperties": false, + "description": "Resolve by naming a variant: compose this one, whatever a context would have matched.", + "required": [ + "schema", + "entity_id", + "variant_id" + ], + "properties": { + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "entity_id": { + "type": "string", + "description": "The conditional entity to resolve. Resolution is always scoped to exactly one.", + "example": "price-sp26d1yo" + }, + "variant_id": { + "type": "string", + "description": "The variant to compose. Condition matching is skipped, the `default` fallback does not\napply, and `results` carries exactly one entry. A variant of another entity is\n`VARIANT_NOT_FOUND`.\n", + "example": "var-46045" + }, + "as_of": { + "type": "string", + "description": "The instant the version is selected at — the version with the latest `valid_from` at or\nbefore it. Defaults to now. A pinned variant whose first version is later is\n`NO_ACTIVE_VERSION`, carrying the instant in `details.as_of`.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most\nmillisecond precision.\n", + "example": "2027-03-15T00:00:00Z" + }, + "options": { + "$ref": "#/components/schemas/PinnedResolveOptions" + } + } + }, + "ResolveContext": { + "type": "object", + "additionalProperties": true, + "description": "The situation to resolve for: a flat map keyed by condition name. A condition left out\nmatches only variants that leave it unpinned; an empty map therefore returns the `default`\nvariant.\n\nEach value is an exact value, typed by its condition, or a single-operator predicate:\n\n- `{ \"lt\": v }`, `{ \"lte\": v }`, `{ \"gt\": v }`, `{ \"gte\": v }` — order, against a `number`\n or `date` condition\n- `{ \"in\": [...] }` — membership, against a `string`, `select` or `number` condition\n- `{ \"between\": \"2026-03-01\" }` — `daterange` containment, which a plain date also means\n- `{ \"exists\": true }` — pinned to any value; `{ \"exists\": false }` — left unpinned\n\nAn `in` list carries at most 50,000 values. A `string` or `select` matches exactly and\ncase-sensitively. A `location` of format\n`zipcode` is the postal code itself; one of format `zipcode_town` is an object carrying\nboth, whose town is compared case- and whitespace-insensitively.\n\n`default` and names beginning with `_` are reserved and cannot be supplied.\n", + "example": { + "postal_code": "46045", + "consumption": { + "lt": 5000 + } + } + }, + "ResolveOptions": { + "type": "object", + "additionalProperties": false, + "description": "The options a context resolve accepts. A pin takes `PinnedResolveOptions` instead.", + "properties": { + "resolve_one": { + "type": "boolean", + "default": false, + "description": "Ask for an unambiguous answer: several applicable variants become\n`AMBIGUOUS_RESOLUTION`, and none becomes `NO_MATCHES`.\n" + }, + "hydrate": { + "type": "boolean", + "default": false, + "description": "Return the entities a relation attribute references in place of the references, one\nlevel deep, as an entity read with hydration does. Applied after composition, so a\nrelation this variant's version replaced is hydrated too.\n\nA referenced entity that is itself conditional is returned unresolved, carrying its own\nflag. Costs one fetch per distinct referenced entity, with no per-attribute limit.\n" + } + } + }, + "PinnedResolveOptions": { + "type": "object", + "additionalProperties": false, + "description": "The options a pinned resolve accepts — `hydrate` and nothing else. `resolve_one` has nothing\nto change where the answer is one result or a 404, so a body sending it is a `400`.\n", + "properties": { + "hydrate": { + "type": "boolean", + "default": false, + "description": "Return the entities a relation attribute references in place of the references, one\nlevel deep, as an entity read with hydration does. Applied after composition, so a\nrelation this variant's version replaced is hydrated too.\n\nA referenced entity that is itself conditional is returned unresolved, carrying its own\nflag. Costs one fetch per distinct referenced entity, with no per-attribute limit.\n" + } + } + }, + "ResolvedVariants": { + "type": "object", + "required": [ + "results" + ], + "properties": { + "results": { + "type": "array", + "description": "One composed payload per applicable variant, capped at 100 — a context selecting more is\n`TOO_MANY_MATCHES`. Unordered.\n", + "items": { + "$ref": "#/components/schemas/ResolvedVariant" + } + } + } + }, + "ResolvedVariant": { + "type": "object", + "additionalProperties": true, + "description": "The entity as this variant leaves it — every attribute of a plain entity read with the\napplicable version's overrides applied — plus the discriminators below.\n", + "required": [ + "_id", + "_variant_id", + "_version_valid_from", + "_conditions", + "_inert_overrides" + ], + "properties": { + "_id": { + "type": "string", + "description": "The logical entity's id, the same one a plain entity read returns.", + "example": "price-sp26d1yo" + }, + "_variant_id": { + "type": "string", + "description": "The variant these values came from — what an order or contract pins.", + "example": "var-46045" + }, + "_version_valid_from": { + "type": "string", + "description": "The `valid_from` of the version applied for the requested `as_of`.", + "example": "2027-01-01T00:00:00.000Z" + }, + "_conditions": { "allOf": [ { - "$ref": "#/components/schemas/PinnedConditions" - } - ], - "description": "Optional, and never applied: a variant's conditions are fixed when it is created. Accepted\nonly so that a client building its body from the version it loaded is not forced to strip\nthem out, and refused when they describe a different situation from the stored one.\n" - } - } - }, - "ReplaceVersionRequest": { - "type": "object", - "additionalProperties": false, - "required": [ - "values", - "_revision" - ], - "properties": { - "values": { - "allOf": [ + "$ref": "#/components/schemas/VariantConditions" + } + ], + "description": "The conditions this variant pins, plus the boolean `default` discriminator." + }, + "_inert_overrides": { + "type": "array", + "description": "The variant's stored overrides this payload did not apply, and why. Always present, and\nempty in the ordinary case. Computed per read against the schema as it stands, so\ngranting or withdrawing `overridable_attribute` changes it without any data being\nrewritten.\n", + "items": { + "$ref": "#/components/schemas/InertOverride" + } + } + } + }, + "CreateVariantRequest": { + "type": "object", + "additionalProperties": false, + "required": [ + "values" + ], + "properties": { + "conditions": { + "$ref": "#/components/schemas/PinnedConditions" + }, + "default": { + "type": "boolean", + "default": false, + "description": "Mark this variant as the entity's fallback, served when no other variant applies. It can\npin nothing else, and an entity may have one; a second is `TUPLE_CONFLICT`. Available to\nevery conditional entity without anything being declared in the schema.\n" + }, + "valid_from": { + "type": "string", + "description": "When the first version takes effect. Defaults to now. An RFC 3339 date (`2026-01-01`,\nread as midnight UTC) or date-time, to at most millisecond precision.\n", + "example": "2027-01-01T00:00:00Z" + }, + "values": { + "$ref": "#/components/schemas/VariantValues" + } + } + }, + "VariantConditions": { + "type": "object", + "additionalProperties": true, + "required": [ + "default" + ], + "description": "A variant's pinned conditions as a reader sees them: the pins the schema declares, plus a\nboolean `default` saying whether this is the entity's fallback.\n", + "properties": { + "default": { + "type": "boolean" + } + }, + "example": { + "postal_code": "46045", + "default": false + } + }, + "PinnedConditions": { + "type": "object", + "additionalProperties": true, + "description": "The situation this variant applies to: a flat map keyed by condition name. A condition left\nout is a wildcard, which is what makes adding a condition to a schema non-breaking for\nexisting variants.\n\nExact values only; predicates belong to reads. Values are stored canonicalized for their\ntype: a `date` becomes millisecond-precision UTC, a `daterange` an object carrying `from`\nand `until` where an empty string is an open end, a `location` of format `zipcode` the\npostal code itself and one of format `zipcode_town` an object carrying both.\n\n`default` and names beginning with `_` are reserved; use the request's `default` flag.\n", + "example": { + "postal_code": "46045" + } + }, + "VariantValues": { + "type": "object", + "additionalProperties": true, + "description": "The values this version overrides on the base entity, keyed by entity field name.\n\nA field is overridable if its attribute declares `overridable_attribute` — which readonly,\nhidden, computed and metadata fields, and types no variant may override, cannot be given —\nor if a capability declaring `overridable_attribute` names it in `managed_fields`, which\nexcludes only readonly and metadata fields.\n\nFields that are not overridable are reported in the write's `warnings` rather than rejected,\nand keep whatever value they already had. An append seeds them from the version in effect at\nits own `valid_from`.\n\nA composite price's `price_components` is an ordinary overridable relation attribute,\nreferencing component entities rather than variants or versions.\n", + "example": { + "unit_amount": 2499, + "unit_amount_decimal": "24.99" + } + }, + "CreatedVariant": { + "type": "object", + "required": [ + "variant_id", + "entity_id", + "schema", + "conditions", + "valid_from", + "values", + "_created_at", + "_updated_at", + "_revision", + "warnings" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "Server-generated. The durable key orders and contracts pin.", + "example": "var-46045" + }, + "entity_id": { + "type": "string", + "example": "price-sp26d1yo" + }, + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantConditions" + } + ], + "description": "The situation this variant applies to, plus the boolean `default` discriminator." + }, + "valid_from": { + "type": "string", + "description": "When the first version takes effect, canonicalized to millisecond-precision UTC.", + "example": "2027-01-01T00:00:00.000Z" + }, + "values": { + "$ref": "#/components/schemas/VariantValues" + }, + "_created_at": { + "type": "string", + "description": "When the first version was created.", + "readOnly": true + }, + "_updated_at": { + "type": "string", + "description": "When the first version was last written.", + "readOnly": true + }, + "_revision": { + "type": "number", + "description": "The revision a later write to this version must carry.", + "readOnly": true + }, + "warnings": { + "type": "array", + "description": "Things worth knowing that did not stop the write. Always present, and empty in the ordinary case.", + "items": { + "$ref": "#/components/schemas/WriteWarning" + } + } + } + }, + "WriteWarning": { + "description": "Something worth knowing that did not stop a write. One vocabulary for every write; `details`\nis typed per `code`, and a write raises each code at most once.\n", + "oneOf": [ + { + "type": "object", + "additionalProperties": false, + "description": "This entity is nearing the number of variants it may hold.", + "required": [ + "code", + "message", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VARIANT_COUNT_APPROACHING_CAP" + ] + }, + "message": { + "type": "string" + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_count", + "cap" + ], + "properties": { + "variant_count": { + "type": "number", + "description": "Variants this entity holds, including the one just written." + }, + "cap": { + "type": "number", + "description": "Variants this entity may hold. Configurable per deploy." + } + } + } + } + }, + { + "type": "object", + "additionalProperties": false, + "description": "What resolves now changed, other than by a newer version taking effect: the version in\neffect was written behind, or removed.\n", + "required": [ + "code", + "message", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "ACTIVE_VERSION_CHANGED" + ] + }, + "message": { + "type": "string" + }, + "details": { + "$ref": "#/components/schemas/VersionMoved" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "description": "What a past-dated (`as_of`) read returns changed: the write landed on, or created, a\nversion dated in the past.\n", + "required": [ + "code", + "message", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "SUPERSEDED_VERSION_WRITTEN" + ] + }, + "message": { + "type": "string" + }, + "details": { + "$ref": "#/components/schemas/VersionMoved" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "description": "Attributes named in the request body that the write did not store, one entry each with\nits own reason. The write itself succeeded.\n", + "required": [ + "code", + "message", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "ATTRIBUTES_NOT_APPLIED" + ] + }, + "message": { + "type": "string" + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "attributes" + ], + "properties": { + "attributes": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/components/schemas/InertOverride" + } + } + } + } + } + } + ] + }, + "VersionMoved": { + "type": "object", + "additionalProperties": false, + "description": "Which version a write moved, and which one was in effect while it did.", + "required": [ + "valid_from" + ], + "properties": { + "valid_from": { + "type": "string", + "description": "The version this write created, changed or removed.", + "example": "2026-08-01T00:00:00.000Z" + }, + "active_valid_from": { + "type": "string", + "description": "The version in effect when the write landed, before it did. Absent when the variant had\nnone. Advisory, and may lag the timeline by milliseconds.\n", + "example": "2026-01-01T00:00:00.000Z" + } + } + }, + "InertOverride": { + "type": "object", + "additionalProperties": false, + "description": "One override that did not apply, and why — reported by a write for the attributes in its\nbody, and by a resolved payload for the stored overrides composition passed over.\n", + "required": [ + "attribute", + "reason" + ], + "properties": { + "attribute": { + "type": "string", + "description": "The attribute's name, as the request body or the stored version spells it.", + "example": "unit_amount" + }, + "reason": { + "$ref": "#/components/schemas/InertOverrideReason" + } + } + }, + "InertOverrideReason": { + "type": "string", + "description": "Why one override did not apply.\n\n- `ATTRIBUTE_NOT_OVERRIDABLE`: the schema declares the attribute without\n `overridable_attribute`, which is an ordinary schema edit away\n- `ATTRIBUTE_READONLY`: the attribute is readonly, and cannot be granted the flag\n- `ATTRIBUTE_HIDDEN`: the attribute is hidden, and cannot be granted the flag\n- `ATTRIBUTE_COMPUTED`: the attribute's value is derived rather than stored\n- `ATTRIBUTE_UNDECLARED`: the schema declares no attribute of that name\n- `TYPE_NOT_OVERRIDABLE`: the attribute's type is not one a variant may override\n- `CAPABILITY_NOT_OVERRIDABLE`: the field is managed by a capability that does not declare\n `overridable_attribute`\n", + "enum": [ + "ATTRIBUTE_NOT_OVERRIDABLE", + "ATTRIBUTE_READONLY", + "ATTRIBUTE_HIDDEN", + "ATTRIBUTE_COMPUTED", + "ATTRIBUTE_UNDECLARED", + "TYPE_NOT_OVERRIDABLE", + "CAPABILITY_NOT_OVERRIDABLE" + ] + }, + "DeletedVariant": { + "type": "object", + "required": [ + "variant_id", + "entity_id", + "schema", + "tuple_released", + "versions_deleted" + ], + "properties": { + "variant_id": { + "type": "string", + "example": "var-46045" + }, + "entity_id": { + "type": "string", + "example": "price-sp26d1yo" + }, + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "tuple_released": { + "type": "boolean", + "description": "Whether this call freed the variant's combination of condition values. `false` where an\nearlier, interrupted attempt had already freed it.\n" + }, + "versions_deleted": { + "type": "number", + "description": "Version rows this call removed." + } + } + }, + "VariantVersion": { + "type": "object", + "description": "One version of one variant: the overrides it carries, the instant it takes effect, and the\nvariant it belongs to. These are the version's own overrides; `:resolve` composes them onto\nthe entity.\n", + "required": [ + "variant_id", + "entity_id", + "schema", + "conditions", + "valid_from", + "values", + "_created_at", + "_updated_at", + "_revision" + ], + "properties": { + "variant_id": { + "type": "string", + "example": "var-46045" + }, + "entity_id": { + "type": "string", + "example": "price-sp26d1yo" + }, + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantConditions" + } + ], + "description": "The situation the variant applies to, plus the boolean `default` discriminator. A\nproperty of the variant: every version carries the same one.\n" + }, + "valid_from": { + "type": "string", + "description": "When this version takes effect, canonicalized to millisecond-precision UTC. Its identity\nwithin the variant.\n", + "example": "2027-01-01T00:00:00.000Z" + }, + "values": { + "$ref": "#/components/schemas/VariantValues" + }, + "_created_at": { + "type": "string", + "description": "When this version was created.", + "readOnly": true + }, + "_updated_at": { + "type": "string", + "description": "When this version was last written.", + "readOnly": true + }, + "_revision": { + "type": "integer", + "description": "The revision a write to this version must carry. Read from a strongly consistent read.", + "readOnly": true, + "example": 3 + } + } + }, + "WrittenVariantVersion": { + "description": "A version as a write left it, together with anything the write moved.", + "allOf": [ + { + "$ref": "#/components/schemas/VariantVersion" + }, + { + "type": "object", + "required": [ + "warnings" + ], + "properties": { + "warnings": { + "type": "array", + "description": "What this write moved, and anything in the body it did not store. Always present,\nand empty in the ordinary case.\n", + "items": { + "$ref": "#/components/schemas/WriteWarning" + } + } + } + } + ] + }, + "DeletedVariantVersion": { + "type": "object", + "required": [ + "variant_id", + "entity_id", + "schema", + "valid_from", + "warnings" + ], + "properties": { + "variant_id": { + "type": "string", + "example": "var-46045" + }, + "entity_id": { + "type": "string", + "example": "price-sp26d1yo" + }, + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "valid_from": { + "type": "string", + "description": "The version removed, canonicalized to millisecond-precision UTC.", + "example": "2027-01-01T00:00:00.000Z" + }, + "warnings": { + "type": "array", + "description": "What the delete moved. Always present, and empty when a scheduled version was withdrawn.", + "items": { + "$ref": "#/components/schemas/WriteWarning" + } + } + } + }, + "AppendVersionRequest": { + "type": "object", + "additionalProperties": false, + "required": [ + "values" + ], + "properties": { + "valid_from": { + "type": "string", + "description": "When this version takes effect. Omit it to mean now; a timestamp read from the caller's\nown clock is already a backdate by the time the server judges it, and earns a warning.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most\nmillisecond precision. A date in the past is accepted; one the variant already has a\nversion at is `VERSION_CONFLICT`.\n", + "example": "2027-01-01T00:00:00Z" + }, + "values": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantValues" + } + ], + "description": "The overrides this version carries. Attributes the variant may not override are seeded\nfrom the version in effect at this version's own `valid_from`.\n" + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/PinnedConditions" + } + ], + "description": "Accepted only unchanged, so a client can send back the body it loaded. A variant's\nconditions are fixed when it is created.\n" + } + } + }, + "ReplaceVersionRequest": { + "type": "object", + "additionalProperties": false, + "required": [ + "values", + "_revision" + ], + "properties": { + "values": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantValues" + } + ], + "description": "The complete set of overrides this version carries. An overridable attribute absent from\nhere stops being overridden; one the variant may not override keeps its stored value.\n" + }, + "_revision": { + "type": "integer", + "minimum": 1, + "description": "The revision read from the version being written. Refused with `WRITE_CONFLICT` if the\nversion has been written since.\n", + "example": 3 + }, + "valid_from": { + "type": "string", + "description": "Accepted only when it names the version being addressed. Moving a version is an append\nand a delete.\n" + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/PinnedConditions" + } + ], + "description": "Accepted only unchanged. A variant's conditions are fixed when it is created." + } + } + }, + "PatchVersionRequest": { + "type": "object", + "additionalProperties": false, + "required": [ + "values", + "_revision" + ], + "properties": { + "values": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantValues" + } + ], + "description": "Only the overrides to change; everything not mentioned is left as stored. `null` sets a\nvalue rather than removing an override — use the replace operation to remove one.\n" + }, + "_revision": { + "type": "integer", + "minimum": 1, + "description": "The revision read from the version being written. Refused with `WRITE_CONFLICT` if the\nversion has been written since.\n", + "example": 3 + }, + "valid_from": { + "type": "string", + "description": "Accepted only when it names the version being addressed." + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/PinnedConditions" + } + ], + "description": "Accepted only unchanged. A variant's conditions are fixed when it is created." + } + } + }, + "ListVariantsRequest": { + "type": "object", + "additionalProperties": false, + "description": "How to narrow and page a variant listing. Every property is optional, so `{}` asks for the\nfirst ten variants in `variant_id` order, but the body itself is required. `conditions` and\n`search` narrow independently and a variant must satisfy both.\n", + "properties": { + "conditions": { + "$ref": "#/components/schemas/VariantConditionFilter" + }, + "search": { + "type": "string", + "description": "Free text matched against the scalar pins — `string`, `select`, `number` and `date`.\n`location` and `daterange` pins are stored structured and are not matched.\n", + "example": "460" + }, + "sort": { + "type": "string", + "description": "`conditions.:asc` or `conditions.:desc`, for a `string`, `select`, `number`\nor `date` pin. `variant_id:asc` is always appended, so the order is total.\n", + "example": "conditions.postal_code:asc" + }, + "from": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "The offset to read from, ignored when a `cursor` is sent. Bounded together with `size`\nby the search index's offset window; a page reaching past it is\n`OFFSET_WINDOW_EXCEEDED`, which reports the window.\n" + }, + "size": { + "type": "integer", + "minimum": 1, + "default": 10, + "description": "Rows per page. Clamped silently at 1000." + }, + "cursor": { + "type": "string", + "description": "Continue from a previous response's `next`, which is where a caller goes when the offset\nwindow runs out. Opaque, and valid only with the `conditions`, `search` and `sort` it\nwas issued with.\n", + "example": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" + } + } + }, + "VariantTreeRequest": { + "type": "object", + "additionalProperties": false, + "description": "The variants list's request plus `as_of`, the instant each row's version is selected at.\n`size` is clamped at 100 here; every other property means what it means on the list.\n", + "properties": { + "conditions": { + "$ref": "#/components/schemas/VariantConditionFilter" + }, + "search": { + "type": "string", + "description": "Free text matched against the scalar pins — `string`, `select`, `number` and `date`.\n`location` and `daterange` pins are stored structured and are not matched.\n", + "example": "460" + }, + "sort": { + "type": "string", + "description": "`conditions.:asc` or `conditions.:desc`, for a `string`, `select`, `number`\nor `date` pin. `variant_id:asc` is always appended, so the order is total.\n", + "example": "conditions.postal_code:asc" + }, + "from": { + "type": "integer", + "minimum": 0, + "default": 0, + "description": "The offset to read from, ignored when a `cursor` is sent. Bounded together with `size`\nby the search index's offset window; a page reaching past it is\n`OFFSET_WINDOW_EXCEEDED`, which reports the window.\n" + }, + "size": { + "type": "integer", + "minimum": 1, + "default": 10, + "description": "Rows per page. Clamped silently at 100, since every row costs its own version lookup." + }, + "cursor": { + "type": "string", + "description": "Continue from a previous response's `next`, which is where a caller goes when the offset\nwindow runs out. Opaque, and valid only with the `conditions`, `search` and `sort` it\nwas issued with.\n", + "example": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" + }, + "as_of": { + "type": "string", + "description": "The instant each row's version is selected at. Defaults to now. A variant whose first\nversion is later is a row with `status: scheduled` carrying that upcoming version.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most\nmillisecond precision.\n", + "example": "2027-03-15T00:00:00Z" + } + } + }, + "VariantConditionFilter": { + "type": "object", + "additionalProperties": true, + "description": "Which pins a variant must carry to be listed: a flat map keyed by condition name, taking the\nsame exact values and predicates a resolve context does. A condition left out is not\nfiltered on. An `in` list carries at most 50,000 values.\n\nA variant matches only where it pins the condition — unlike `:resolve`, where an unpinned\ncondition matches any value. `{ \"exists\": false }` selects the variants that leave it\nunpinned.\n\n`default` is accepted as an exact boolean and takes no predicate: `true` selects the\nentity's fallback variant, `false` every variant that is not it. Names beginning with `_`\nare reserved.\n", + "example": { + "postal_code": "46045", + "consumption": { + "lt": 5000 + } + } + }, + "VariantList": { + "type": "object", + "required": [ + "hits", + "results" + ], + "properties": { + "hits": { + "type": "integer", + "description": "How many variants match in total, exactly — not how many this page carries.", + "example": 8128 + }, + "results": { + "type": "array", + "items": { + "$ref": "#/components/schemas/VariantListRow" + } + }, + "next": { + "type": "string", + "description": "The cursor that continues this listing, absent on the last page. Send it back as\n`cursor`, with the same filter, search and sort.\n", + "example": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" + } + } + }, + "VariantListRow": { + "type": "object", + "description": "One variant as a listing reports it: which variant it is and what it pins.", + "required": [ + "variant_id", + "entity_id", + "schema", + "conditions" + ], + "properties": { + "variant_id": { + "type": "string", + "example": "var-46045" + }, + "entity_id": { + "type": "string", + "example": "price-sp26d1yo" + }, + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantConditions" + } + ], + "description": "The situation this variant applies to, plus the boolean `default` discriminator.\nMembership of a page may lag a write by moments; the pins themselves never do.\n" + } + } + }, + "VariantTree": { + "type": "object", + "required": [ + "hits", + "results" + ], + "properties": { + "hits": { + "type": "integer", + "description": "How many variants match in total, exactly — not how many this page carries.", + "example": 8128 + }, + "results": { + "type": "array", + "description": "One row per matching variant, in the requested order. A variant mid-delete is omitted,\nso `results` can be shorter than `hits` implies.\n", + "items": { + "$ref": "#/components/schemas/VariantTreeRow" + } + }, + "next": { + "type": "string", + "description": "The cursor that continues this listing, absent on the last page. Send it back as\n`cursor`, with the same filter, search and sort; `as_of` may change between pages.\n", + "example": "eyJmcm9tIjoyNSwibGlzdGluZyI6IjNmOWMxZTJhIn0" + } + } + }, + "VariantTreeRow": { + "type": "object", + "description": "A listing row plus the one version the tree shows for it, and the status saying which.", + "required": [ + "variant_id", + "entity_id", + "schema", + "conditions", + "status", + "version" + ], + "properties": { + "variant_id": { + "type": "string", + "example": "var-46045" + }, + "entity_id": { + "type": "string", + "example": "price-sp26d1yo" + }, + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantConditions" + } + ], + "description": "The situation this variant applies to, plus the boolean `default` discriminator.\nMembership of a page may lag a write by moments; the pins themselves never do.\n" + }, + "status": { + "$ref": "#/components/schemas/VariantTreeRowStatus" + }, + "version": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantVersionSnapshot" + } + ], + "description": "The version in effect at `as_of`, or the variant's upcoming first one where every\nversion is still ahead of it. `status` says which. Always present.\n" + } + } + }, + "VariantTreeRowStatus": { + "type": "string", + "description": "Whether a tree row's version is the one in effect at `as_of`, or one still ahead of it.\n\n- `active`: the version with the latest `valid_from` at or before `as_of`\n- `scheduled`: the variant's first version, which is later than `as_of`\n", + "enum": [ + "active", + "scheduled" + ] + }, + "VariantVersionSnapshot": { + "type": "object", + "description": "One version of one variant as a listing reports it: `VariantVersion` without `_revision`.\nRead the version through its own `GET` to get the revision a write must carry.\n", + "required": [ + "variant_id", + "entity_id", + "schema", + "conditions", + "valid_from", + "values", + "_created_at", + "_updated_at" + ], + "properties": { + "variant_id": { + "type": "string", + "example": "var-46045" + }, + "entity_id": { + "type": "string", + "example": "price-sp26d1yo" + }, + "schema": { + "$ref": "#/components/schemas/ConditionalEntitySlug" + }, + "conditions": { + "allOf": [ + { + "$ref": "#/components/schemas/VariantConditions" + } + ], + "description": "The situation the variant applies to, plus the boolean `default` discriminator. A\nproperty of the variant: every version carries the same one.\n" + }, + "valid_from": { + "type": "string", + "description": "When this version takes effect, canonicalized to millisecond-precision UTC. Its identity\nwithin the variant.\n", + "example": "2027-01-01T00:00:00.000Z" + }, + "values": { + "$ref": "#/components/schemas/VariantValues" + }, + "_created_at": { + "type": "string", + "description": "When this version was created.", + "readOnly": true + }, + "_updated_at": { + "type": "string", + "description": "When this version was last written.", + "readOnly": true + } + } + }, + "VariantVersionList": { + "type": "object", + "required": [ + "results" + ], + "properties": { + "results": { + "type": "array", + "description": "A page of the variant's timeline, in the requested `order`.", + "items": { + "$ref": "#/components/schemas/VariantVersionSnapshot" + } + }, + "next": { + "type": "string", + "description": "The cursor that continues this timeline, absent only on the last page — the only\nend-of-data signal, since a short or empty page can still carry one. Send it back as\n`cursor`, against the same variant and `order`.\n", + "example": "eyJzayI6IlYjcHJpY2Utc3AyNmQxeW8jdmFyLTQ2MDQ1IzIwMjYtMDEtMDFUMDA6MDA6MDAuMDAwWiIsIm9yZGVyIjoiYXNjIn0" + } + } + }, + "BatchUpsertVariantsRequest": { + "type": "object", + "additionalProperties": false, + "description": "A batch of variant writes under one schema, each item naming the entity it writes to.", + "required": [ + "items" + ], + "properties": { + "correlation_id": { + "type": "string", + "description": "An opaque string echoed back verbatim when it was sent, and never interpreted.", + "example": "tariff-refresh-2027-01" + }, + "items": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "description": "The writes to apply, in the order they should apply where two of them address the same\nvariant. At most 100 per call, which is distinct from the per-entity variant cap.\n", + "items": { + "$ref": "#/components/schemas/BatchUpsertItem" + } + } + } + }, + "BatchUpsertItem": { + "type": "object", + "additionalProperties": false, + "description": "One variant write: the single-item create's body plus `entity_id`, and no `variant_id`. An\nexisting condition tuple appends a version to the variant holding it rather than conflicting.\n", + "required": [ + "entity_id", + "values" + ], + "properties": { + "entity_id": { + "type": "string", + "description": "The conditional entity this item writes to.", + "example": "price-sp26d1yo" + }, + "conditions": { + "$ref": "#/components/schemas/PinnedConditions" + }, + "default": { + "type": "boolean", + "default": false, + "description": "Mark this variant as the entity's fallback, as a create does. An item that pins nothing\nand is not the default is `VARIANT_UNPINNED`.\n" + }, + "valid_from": { + "type": "string", + "description": "When the version this item writes takes effect. Omitted, it is a last-write-wins write\nwith no `skipped` detection; a past instant is accepted and reported in this item's\n`warnings`.\n\nAn RFC 3339 date (`2026-01-01`, read as midnight UTC) or date-time, to at most\nmillisecond precision.\n", + "example": "2027-01-01T00:00:00Z" + }, + "values": { + "$ref": "#/components/schemas/VariantValues" + } + } + }, + "BatchDeleteVariantsRequest": { + "type": "object", + "additionalProperties": false, + "description": "A batch of variant and version deletes under one schema, each item naming the entity it removes from.", + "required": [ + "items" + ], + "properties": { + "correlation_id": { + "type": "string", + "description": "An opaque string echoed back verbatim when it was sent, and never interpreted.", + "example": "postal-code-cleanup-2026-09" + }, + "items": { + "type": "array", + "minItems": 1, + "maxItems": 100, + "description": "The deletes to apply, in the order they should apply where two of them address the same\nvariant — decided after every condition tuple has been resolved to a variant id. At most\n100 per call.\n", + "items": { + "$ref": "#/components/schemas/BatchDeleteItem" + } + } + } + }, + "BatchDeleteItem": { + "description": "One delete: the variant, addressed by id or by the condition tuple it pins, and optionally\nthe one version of it to remove. An item carrying both matches neither branch and is an\nenvelope `400`.\n", + "oneOf": [ + { + "$ref": "#/components/schemas/BatchDeleteByVariantId" + }, + { + "$ref": "#/components/schemas/BatchDeleteByConditions" + } + ] + }, + "BatchDeleteByVariantId": { + "type": "object", + "additionalProperties": false, + "description": "A delete addressing its variant by id.", + "required": [ + "entity_id", + "variant_id" + ], + "properties": { + "entity_id": { + "type": "string", + "description": "The conditional entity the variant belongs to. Required: a variant id alone addresses nothing.", + "example": "price-sp26d1yo" + }, + "variant_id": { + "type": "string", + "description": "The variant to remove, or whose version to remove.", + "example": "var-46045" + }, + "valid_from": { + "type": "string", + "description": "The one version to remove, by the instant it takes effect. Omitted, the whole variant\ngoes. An RFC 3339 date or date-time, canonicalized before it is matched.\n", + "example": "2027-01-01T00:00:00Z" + } + } + }, + "BatchDeleteByConditions": { + "type": "object", + "additionalProperties": false, + "description": "A delete addressing its variant by the situation it applies to.\n\n`conditions` is optional because the fallback variant pins nothing: address it with\n`default: true` and no `conditions`. An item that ends up addressing no variant at all is a\nper-item `VARIANT_UNPINNED`, and one marking `default` beside `conditions` is refused per\nitem with no code.\n", + "required": [ + "entity_id" + ], + "properties": { + "entity_id": { + "type": "string", + "description": "The conditional entity the variant belongs to.", + "example": "price-sp26d1yo" + }, + "conditions": { + "$ref": "#/components/schemas/PinnedConditions" + }, + "default": { + "type": "boolean", + "default": false, + "description": "Address the entity's fallback variant, the one served when nothing else applies." + }, + "valid_from": { + "type": "string", + "description": "The one version to remove, by the instant it takes effect. Omitted, the whole variant\ngoes. An RFC 3339 date or date-time, canonicalized before it is matched.\n", + "example": "2027-01-01T00:00:00Z" + } + } + }, + "BatchUpsertResult": { + "type": "object", + "description": "What a batch upsert did: one entry per item, in request order, and a count per outcome.", + "required": [ + "counts", + "results" + ], + "properties": { + "correlation_id": { + "type": "string", + "description": "The `correlation_id` the request carried, echoed only when it was sent.", + "example": "tariff-refresh-2027-01" + }, + "counts": { + "$ref": "#/components/schemas/BatchUpsertCounts" + }, + "results": { + "type": "array", + "description": "One entry per item, in request order, which is what maps an outcome back to its source row.", + "items": { + "$ref": "#/components/schemas/BatchUpsertResultEntry" + } + } + } + }, + "BatchDeleteResult": { + "type": "object", + "description": "What a batch delete did: one entry per item, in request order, and a count per outcome.", + "required": [ + "counts", + "results" + ], + "properties": { + "correlation_id": { + "type": "string", + "description": "The `correlation_id` the request carried, echoed only when it was sent.", + "example": "postal-code-cleanup-2026-09" + }, + "counts": { + "$ref": "#/components/schemas/BatchDeleteCounts" + }, + "results": { + "type": "array", + "description": "One entry per item, in request order, which is what maps an outcome back to its source row.", + "items": { + "$ref": "#/components/schemas/BatchDeleteResultEntry" + } + } + } + }, + "BatchUpsertOutcome": { + "type": "string", + "description": "What one upsert item did, derived from what was stored.\n\n- `variant_created`: the condition tuple was unknown, so a variant and its first version\n were created\n- `version_created`: the tuple was known and had no version at the item's `valid_from`\n- `updated`: a version existed at that exact instant and was written in place\n- `skipped`: the values are identical to what is stored; not detected for an item without\n `valid_from`\n- `error`: this item alone failed, and the entry's `error` says why\n", + "enum": [ + "variant_created", + "version_created", + "updated", + "skipped", + "error" + ] + }, + "BatchDeleteOutcome": { + "type": "string", + "description": "What one delete item did.\n\n- `deleted`: the variant, or the one version the item named, is gone\n- `skipped`: the item addressed no such variant or version; a missing entity is an `error`\n- `error`: this item alone failed, and the entry's `error` says why\n", + "enum": [ + "deleted", + "skipped", + "error" + ] + }, + "BatchUpsertCounts": { + "type": "object", + "additionalProperties": false, + "description": "How many items reached each outcome. Keyed by exactly the values of `BatchUpsertOutcome`,\nall present, and summing to the length of `results`.\n", + "required": [ + "variant_created", + "version_created", + "updated", + "skipped", + "error" + ], + "properties": { + "variant_created": { + "type": "integer", + "example": 1 + }, + "version_created": { + "type": "integer", + "example": 1 + }, + "updated": { + "type": "integer", + "example": 1 + }, + "skipped": { + "type": "integer", + "example": 1 + }, + "error": { + "type": "integer", + "example": 1 + } + } + }, + "BatchDeleteCounts": { + "type": "object", + "additionalProperties": false, + "description": "How many items reached each outcome. Keyed by exactly the values of `BatchDeleteOutcome`,\nall present, and summing to the length of `results`.\n", + "required": [ + "deleted", + "skipped", + "error" + ], + "properties": { + "deleted": { + "type": "integer", + "example": 1 + }, + "skipped": { + "type": "integer", + "example": 1 + }, + "error": { + "type": "integer", + "example": 1 + } + } + }, + "BatchUpsertResultEntry": { + "type": "object", + "additionalProperties": false, + "description": "What one upsert item did. Position in `results` maps it back to its source row.", + "required": [ + "outcome", + "entity_id", + "warnings" + ], + "properties": { + "outcome": { + "$ref": "#/components/schemas/BatchUpsertOutcome" + }, + "entity_id": { + "type": "string", + "description": "The entity this item wrote to, echoed from the item.", + "example": "price-sp26d1yo" + }, + "variant_id": { + "type": "string", + "description": "The variant this item created or wrote to. Present on every outcome but `error`.", + "example": "var-46045" + }, + "valid_from": { + "type": "string", + "description": "The version this item wrote, canonicalized to millisecond-precision UTC. Present on\nevery outcome but `error`, including for an item that sent none.\n", + "example": "2027-01-01T00:00:00.000Z" + }, + "warnings": { + "type": "array", + "description": "Things worth knowing that did not stop this item's write. Always present and possibly\nempty, on every outcome. Fires per item, with no batch-level deduplication.\n", + "items": { + "$ref": "#/components/schemas/WriteWarning" + } + }, + "error": { + "allOf": [ + { + "$ref": "#/components/schemas/ConditionalPricingError" + } + ], + "description": "Why this item failed, present only with `outcome: error`: the codes a variant create\nraises, plus `ENTITY_NOT_FOUND`, `ENTITY_TYPE_MISMATCH` and `ENTITY_NOT_CONDITIONAL`,\nwhich are per item because each item names its own entity. Never `TUPLE_CONFLICT` or\n`VERSION_CONFLICT`.\n" + } + } + }, + "BatchDeleteResultEntry": { + "type": "object", + "additionalProperties": false, + "description": "What one delete item did. Position in `results` maps it back to its source row.", + "required": [ + "outcome", + "entity_id", + "warnings" + ], + "properties": { + "outcome": { + "$ref": "#/components/schemas/BatchDeleteOutcome" + }, + "entity_id": { + "type": "string", + "description": "The entity this item removed from, echoed from the item.", + "example": "price-sp26d1yo" + }, + "variant_id": { + "type": "string", + "description": "The variant this item removed, or whose version it removed. Present wherever it is\nknown, so a `skipped` entry for a tuple no variant pins names none.\n", + "example": "var-46045" + }, + "valid_from": { + "type": "string", + "description": "The version this item removed, canonicalized to millisecond-precision UTC. Absent where\nthe item removed the whole variant.\n", + "example": "2027-01-01T00:00:00.000Z" + }, + "warnings": { + "type": "array", + "description": "Things worth knowing that did not stop this item's delete, chiefly which reads the\nremoval moved. Always present and possibly empty, on every outcome.\n", + "items": { + "$ref": "#/components/schemas/WriteWarning" + } + }, + "error": { + "allOf": [ + { + "$ref": "#/components/schemas/ConditionalPricingError" + } + ], + "description": "Why this item failed, present only with `outcome: error`:\n`LAST_VERSION_UNDELETABLE`, `VARIANT_UNPINNED`, the codes a condition tuple that cannot\nbe canonicalized raises, `IDENTIFIER_INVALID`, `VALID_FROM_INVALID`, `WRITE_CONFLICT`,\nand the per-item `ENTITY_NOT_FOUND`, `ENTITY_TYPE_MISMATCH` and\n`ENTITY_NOT_CONDITIONAL`. A missing variant or version is `skipped` instead.\n" + } + } + }, + "Error": { + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string", + "description": "Error message" + }, + "status": { + "type": "number", + "description": "The HTTP status code" + }, + "cause": { + "type": "string", + "description": "The cause of the error (visible for bad requests - http 400)" + } + } + }, + "ReportedError": { + "description": "The `error` field of an error response: the message, or — where the request failed\nvalidation before any handler ran — the validation errors themselves.\n", + "oneOf": [ + { + "type": "string", + "description": "The message, the same string as `message`.", + "example": "The conditions requested for variant var-46045 are already pinned" + }, + { + "type": "array", + "description": "One entry per validation failure, as the request validator reported it.", + "items": { + "type": "object", + "additionalProperties": true + } + } + ] + }, + "ConditionalPricingError": { + "description": "An error from a conditional-pricing operation, carrying a `code` plus the structured data\nthat code explains. `details` is typed per code: narrow on `code` and the object under it\ndeclares exactly the fields that code sends.\n\nA request these schemas reject is answered by the request validator with a message and\ncarries neither `code` nor `details` — the last member of the union.\n", + "allOf": [ + { + "$ref": "#/components/schemas/Error" + }, + { + "type": "object", + "properties": { + "error": { + "allOf": [ + { + "$ref": "#/components/schemas/ReportedError" + } + ], + "description": "What went wrong. The same string as `message`, except on a request-validation\nfailure, which puts the list of validation errors here instead.\n" + } + } + }, + { + "oneOf": [ + { + "type": "object", + "description": "No conditional entity type by that slug.", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "SCHEMA_NOT_FOUND" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema" + ], + "properties": { + "schema": { + "type": "string", + "description": "The entity type the request addressed.", + "example": "price" + } + } + } + } + }, + { + "type": "object", + "description": "The schema holds no entity with that id.", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "ENTITY_NOT_FOUND" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema", + "entity_id" + ], + "properties": { + "schema": { + "type": "string", + "description": "The entity type the request addressed.", + "example": "price" + }, + "entity_id": { + "type": "string", + "description": "The conditional entity the request addressed.", + "example": "price-sp26d1yo" + } + } + } + } + }, + { + "type": "object", + "description": "That entity id belongs to an entity of a different type than the `{slug}` segment\nnamed. Correct the slug and send the request again.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "ENTITY_TYPE_MISMATCH" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema", + "entity_id", + "actual_schema" + ], + "properties": { + "schema": { + "type": "string", + "description": "The entity type the request addressed.", + "example": "price" + }, + "entity_id": { + "type": "string", + "description": "The conditional entity the request addressed.", + "example": "price-sp26d1yo" + }, + "actual_schema": { + "type": "string", + "description": "The entity type that id belongs to. Where it is a conditional entity type,\nit is the slug to send instead.\n", + "example": "product" + } + } + } + } + }, + { + "type": "object", + "description": "The entity is of the type the slug named and was not created with `is_conditional`,\nwhich is fixed at creation. Reading and writing the entity itself are unaffected.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "ENTITY_NOT_CONDITIONAL" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema", + "entity_id" + ], + "properties": { + "schema": { + "type": "string", + "description": "The entity type the request addressed.", + "example": "price" + }, + "entity_id": { + "type": "string", + "description": "The conditional entity the request addressed.", + "example": "price-sp26d1yo" + } + } + } + } + }, + { + "type": "object", + "description": "This entity has no such variant.", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VARIANT_NOT_FOUND" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "entity_id", + "variant_id" + ], + "properties": { + "entity_id": { + "type": "string", + "description": "The conditional entity the request addressed.", + "example": "price-sp26d1yo" + }, + "variant_id": { + "type": "string", + "description": "The variant the request addressed.", + "example": "var-46045" + } + } + } + } + }, + { + "type": "object", + "description": "No version at that `valid_from` — never written, or deleted since. A version is\naddressed by the exact instant it takes effect from; for the version in effect at an\ninstant, see `NO_ACTIVE_VERSION`.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VERSION_NOT_FOUND" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id", + "valid_from" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The variant the request addressed.", + "example": "var-46045" + }, + "valid_from": { + "type": "string", + "description": "The version the request addressed, by the instant it takes effect from.", + "example": "2027-01-01T00:00:00.000Z" + } + } + } + } + }, + { + "type": "object", + "description": "Nothing applied to the given context and the entity has no `default` variant. Only\nreachable with `resolve_one`; without it the same situation is a `200` carrying an\nempty `results`.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "NO_MATCHES" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "schema", + "entity_id" + ], + "properties": { + "schema": { + "type": "string", + "description": "The entity type the request addressed.", + "example": "price" + }, + "entity_id": { + "type": "string", + "description": "The conditional entity the resolve was scoped to.", + "example": "price-sp26d1yo" + } + } + } + } + }, + { + "type": "object", + "description": "The variant has no version in effect at the instant asked about — typically a\nvariant staged ahead of its launch. Address one of its versions by `valid_from` to\nread or edit it before it takes effect.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "NO_ACTIVE_VERSION" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id", + "as_of" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The variant the request addressed.", + "example": "var-46045" + }, + "as_of": { + "type": "string", + "description": "The instant a version in effect was asked for at.", + "example": "2026-06-01T00:00:00.000Z" + } + } + } + } + }, + { + "type": "object", + "description": "Several variants apply to the given context while a single result was requested.", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "AMBIGUOUS_RESOLUTION" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "candidates" + ], + "properties": { + "candidates": { + "type": "array", + "minItems": 2, + "description": "Every variant that applied, each with the conditions it pins.", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id", + "conditions" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The candidate variant.", + "example": "var-46045" + }, + "conditions": { + "$ref": "#/components/schemas/VariantConditions" + } + } + } + } + } + } + } + }, + { + "type": "object", + "description": "The condition tuple this write claims is already held. Persistent, unlike\n`WRITE_CONFLICT`: the same request fails the same way until the holder changes.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "TUPLE_CONFLICT" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The variant the write addressed.", + "example": "var-46045" + }, + "conflicting_variant_id": { + "type": "string", + "description": "The variant already holding the tuple, where the write read it back.", + "example": "var-50667" + } + } + } + } + }, + { + "type": "object", + "description": "A version already exists at the given `valid_from` on that variant.", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VERSION_CONFLICT" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id", + "valid_from" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The variant the write addressed.", + "example": "var-46045" + }, + "valid_from": { + "type": "string", + "description": "The instant already claimed by a version of that variant.", + "example": "2027-01-01T00:00:00.000Z" + } + } + } + } + }, + { + "type": "object", + "description": "The request names a condition the entity's schema does not define. A *stored* pin on\na condition the schema no longer declares is `VARIANT_PIN_UNDECLARED`.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "CONDITION_UNDEFINED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name" + ], + "properties": { + "condition_name": { + "type": "string", + "description": "The condition the request named and the schema does not define.", + "example": "postal_code" + } + } + } + } + }, + { + "type": "object", + "description": "A variant a resolve would compose pins a condition the entity's schema no longer\ndeclares, which would make it match every context. Declare the condition again, or\nremove the variants pinning it — found with `variants:list` or the tree, and removed\nby id.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VARIANT_PIN_UNDECLARED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name", + "variant_id" + ], + "properties": { + "condition_name": { + "type": "string", + "description": "The condition the variant pins and the schema no longer declares.", + "example": "postal_code" + }, + "variant_id": { + "type": "string", + "description": "One variant carrying such a pin.", + "example": "var-46045" + } + } + } + } + }, + { + "type": "object", + "description": "The requested operator is not applicable to the condition's type.", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "OPERATOR_UNSUPPORTED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name", + "condition_type", + "operator" + ], + "properties": { + "condition_name": { + "type": "string", + "example": "postal_code" + }, + "condition_type": { + "type": "string", + "description": "The type the schema declares that condition with.", + "example": "location" + }, + "operator": { + "type": "string", + "description": "The predicate the context or filter asked for, or `sort` where a listing\nasked to order by a condition whose type has no order.\n", + "example": "between" + } + } + } + } + }, + { + "type": "object", + "description": "A resolve context or listing filter value that is malformed for its condition's type.", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "CONTEXT_FORMAT_INVALID" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name", + "expected" + ], + "properties": { + "condition_name": { + "type": "string", + "example": "postal_code" + }, + "expected": { + "type": "string", + "description": "What a value for that condition has to be, in prose.", + "example": "a postal code" + } + } + } + } + }, + { + "type": "object", + "description": "A variant write pins a `select` value absent from its condition's vocabulary. A\ncondition declaring no vocabulary at all is `CONDITION_UNCONFIGURED`, and one whose\n`options` hold nothing readable is `CONDITION_UNREADABLE`.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "CONDITION_VALUE_INVALID" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name", + "value", + "options" + ], + "properties": { + "condition_name": { + "type": "string", + "example": "segment" + }, + "value": { + "description": "The value the write pinned, as it arrived.", + "example": "industrial" + }, + "options": { + "type": "array", + "minItems": 1, + "description": "The vocabulary as enforced, after any entries this deploy cannot read have\nbeen dropped.\n", + "items": { + "type": "string" + }, + "example": [ + "private", + "commercial" + ] + } + } + } + } + }, + { + "type": "object", + "description": "A variant write pins a `select` condition whose `options` are absent or empty. A\n`select` vocabulary is always closed, so one declaring nothing admits nothing; fill\nthe `options` in.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "CONDITION_UNCONFIGURED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name" + ], + "properties": { + "condition_name": { + "type": "string", + "description": "The condition whose vocabulary is not configured yet.", + "example": "segment" + } + } + } + } + }, + { + "type": "object", + "description": "A multi-match resolve found more variants than one response may carry. Narrow the\ncontext; the matches are not reported.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "TOO_MANY_MATCHES" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "limit" + ], + "properties": { + "limit": { + "type": "number", + "description": "The most variants one resolve may compose.", + "example": 100 + } + } + } + } + }, + { + "type": "object", + "description": "Transient write contention. Retryable, unlike `TUPLE_CONFLICT`. The revisions are\npresent where the contention was detected on a specific version.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "WRITE_CONFLICT" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The variant the write addressed.", + "example": "var-46045" + }, + "valid_from": { + "type": "string", + "description": "The version the write addressed, where one was addressed.", + "example": "2027-01-01T00:00:00.000Z" + }, + "expected_revision": { + "type": "number", + "description": "The revision the write required the stored version to still be at.", + "example": 3 + }, + "current_revision": { + "type": "number", + "description": "The revision the version is actually at, where the failed write read it back.", + "example": 4 + } + } + } + } + }, + { + "type": "object", + "description": "A listing's `from` plus `size` reaches past the offset window the search index\nallows — the window bounds the last row a page may contain. The page is not clamped;\npage on with the last response's `next` instead.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "OFFSET_WINDOW_EXCEEDED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "from", + "size", + "window" + ], + "properties": { + "from": { + "type": "integer", + "description": "The offset the request asked for.", + "example": 24990 + }, + "size": { + "type": "integer", + "description": "The page size the request asked for, after clamping.", + "example": 25 + }, + "window": { + "type": "integer", + "description": "The last row this deploy's index will serve from an offset.", + "example": 25000 + } + } + } + } + }, + { + "type": "object", + "description": "A paging cursor could not be used for the read it arrived on. Start the read again\nwithout one; `details.reason` says which check failed.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "CURSOR_INVALID" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "reason" + ], + "properties": { + "reason": { + "type": "string", + "description": "Which check the cursor failed, in prose.", + "example": "The cursor was issued for a different sort order" + } + } + } + } + }, + { + "type": "object", + "description": "The entity already holds every variant it may hold. In a batch, every remaining item\nfor that entity will be refused the same way.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VARIANT_LIMIT_REACHED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_count", + "cap" + ], + "properties": { + "variant_count": { + "type": "number", + "description": "Variants this entity already holds.", + "example": 5000 + }, + "cap": { + "type": "number", + "description": "Variants this entity may hold. Configurable per deploy.", + "example": 5000 + } + } + } + } + }, + { + "type": "object", + "description": "A variant pins a value malformed for its condition's type. `condition_type` is what\na client branches on; `expected` says what the value had to be, which the type alone\ndoes not — a `location` is `location` whichever `format` it declares.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "PIN_FORMAT_INVALID" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name", + "condition_type", + "expected", + "value" + ], + "properties": { + "condition_name": { + "type": "string", + "example": "valid_period" + }, + "condition_type": { + "type": "string", + "description": "The type the schema declares that condition with.", + "example": "daterange" + }, + "expected": { + "type": "string", + "description": "What a pin for that condition has to be, in prose.", + "example": "an object carrying a from and an until date, either may be open" + }, + "value": { + "description": "The value the write pinned, as it arrived.", + "example": "2027-01-01/2027-12-31" + } + } + } + } + }, + { + "type": "object", + "description": "The write pins no condition and is not marked `default`, so it would match every\nresolve. On a delete, the item addresses no variant at all.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VARIANT_UNPINNED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "entity_id" + ], + "properties": { + "entity_id": { + "type": "string", + "description": "The conditional entity the item addressed.", + "example": "price-sp26d1yo" + } + } + } + } + }, + { + "type": "object", + "description": "The delete would leave the variant with no version at all, which would keep its\ncondition tuple claimed while resolving to nothing. Delete the variant instead.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "LAST_VERSION_UNDELETABLE" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id", + "valid_from" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The variant whose last version the delete addressed.", + "example": "var-46045" + }, + "valid_from": { + "type": "string", + "description": "The version the delete addressed, by the instant it takes effect from.", + "example": "2027-01-01T00:00:00.000Z" + } + } + } + } + }, { - "$ref": "#/components/schemas/VariantValues" - } - ], - "description": "The complete set of attribute overrides this version carries. An overridable attribute\nabsent from here stops being overridden.\n\nAttributes the variant may not override are ignored where this carries them, and their\n**stored value is kept rather than dropped** — otherwise a routine full-snapshot write\nwould erase an override the moment its attribute's `overridable_attribute`, `readonly` or\n`hidden` flag happened to be off.\n" - }, - "_revision": { - "type": "integer", - "minimum": 1, - "description": "The revision marker read from the version being written. The write is refused with\n`WRITE_CONFLICT` if the version has been written since.\n\nRequired rather than optional: an optional one is a guarantee every client can opt out of\nby forgetting a field, and the write it protects is the one that overwrites somebody\nelse's edit.\n", - "example": 3 - }, - "valid_from": { - "type": "string", - "description": "Optional, and never applied. Accepted when it names the version being addressed — so a\nclient building its body from what it loaded need not strip it out — and refused when it\nnames another: a version's `valid_from` is its identity, and moving it is an append and a\ndelete rather than an edit.\n" - }, - "conditions": { - "allOf": [ + "type": "object", + "description": "A condition the entity's schema declares in a way this deploy cannot read: a\n`location` whose `format` is unrecognized or absent, or a `select` whose `options`\nhold nothing readable. Repair the definition on the schema.\n\nReads that do not interpret the condition — an unfiltered variants list, the tree, a\nvariant by id, a version timeline — keep working.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "CONDITION_UNREADABLE" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name", + "unreadable" + ], + "properties": { + "condition_name": { + "type": "string", + "description": "The condition whose definition this deploy cannot read.", + "example": "delivery_area" + }, + "unreadable": { + "type": "string", + "description": "Which field of the definition cannot be read, named as the schema spells it.", + "enum": [ + "format", + "options" + ], + "example": "format" + } + } + } + } + }, { - "$ref": "#/components/schemas/PinnedConditions" - } - ], - "description": "Optional, and never applied: a variant's conditions are fixed when it is created. Refused\nwhen they describe a different situation from the stored one.\n" - } - } - }, - "PatchVersionRequest": { - "type": "object", - "additionalProperties": false, - "required": [ - "values", - "_revision" - ], - "properties": { - "values": { - "allOf": [ + "type": "object", + "description": "A listing's `sort` is not a field and direction this API can read. A well-formed\n`sort` naming a condition is refused under that condition's own code instead.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "SORT_INVALID" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "expected" + ], + "properties": { + "expected": { + "type": "string", + "description": "What a `sort` has to be, in prose.", + "example": "conditions.:asc or conditions.:desc, naming a string, select, number or date condition" + } + } + } + } + }, { - "$ref": "#/components/schemas/VariantValues" - } - ], - "description": "Only the attribute overrides to change. Everything not mentioned is left as stored.\n\n`null` is a value like any other here rather than a deletion; to stop overriding an\nattribute, send the complete snapshot without it through the replace operation.\n" - }, - "_revision": { - "type": "integer", - "minimum": 1, - "description": "The revision marker read from the version being written. The write is refused with\n`WRITE_CONFLICT` if the version has been written since.\n", - "example": 3 - }, - "valid_from": { - "type": "string", - "description": "Optional, never applied, and refused when it names a version other than the one addressed." - }, - "conditions": { - "allOf": [ + "type": "object", + "description": "The fallback marker — `default` or `_default` — used as though it were a condition.\nMark the variant `default` instead, or leave the marker out of the context.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "DEFAULT_MARKER_RESERVED" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_name" + ], + "properties": { + "condition_name": { + "type": "string", + "description": "The marker, spelled as the request spelled it.", + "example": "default" + } + } + } + } + }, { - "$ref": "#/components/schemas/PinnedConditions" - } - ], - "description": "Optional, and never applied. A partial update that tries to change a pinned condition value\nis refused — this is the path that rule is most likely to be broken on by accident.\n" - } - } - }, - "Error": { - "required": [ - "message" - ], - "properties": { - "message": { - "type": "string", - "description": "Error message" - }, - "status": { - "type": "number", - "description": "The HTTP status code" - }, - "cause": { - "type": "string", - "description": "The cause of the error (visible for bad requests - http 400)" - } - } - }, - "ConditionalPricingError": { - "description": "An error from a conditional-pricing operation, carrying a machine-readable `code`\nfrom the conditional-pricing vocabulary plus any structured data about the failure,\nso a client can branch on the kind of failure rather than parse the message.\nReferenced only by the operations that emit these codes; every other operation\nkeeps the plain `Error` shape.\n", - "allOf": [ - { - "$ref": "#/components/schemas/Error" - }, - { - "type": "object", - "properties": { - "error": { - "type": "string", - "description": "The error message. Carries the same string as `message`, which the shared `Error`\nschema requires — `error` is the field responses have always used, and every caller\nto date reads. Declared here rather than on the shared `Error` because a request\nvalidation failure puts a list of validation errors in this field instead of a\nstring, and those responses reference `Error` directly.\n" + "type": "object", + "description": "A variant marked `default` that also pins real conditions. Drop `default` to keep\nthe pins, or drop the pins to keep the fallback.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "DEFAULT_VARIANT_PINS_CONDITIONS" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "condition_names" + ], + "properties": { + "condition_names": { + "type": "array", + "description": "The conditions the write pinned beside the marker.", + "items": { + "type": "string" + }, + "example": [ + "postal_code" + ] + } + } + } + } }, - "code": { - "$ref": "#/components/schemas/ConditionalPricingErrorCode" + { + "type": "object", + "description": "A version write asking for a different `valid_from` than the version its own address\nnames. Moving a version is an append and a delete; a body repeating the `valid_from`\nit was read with is accepted.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VALID_FROM_IMMUTABLE" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "addressed", + "requested" + ], + "properties": { + "addressed": { + "type": "string", + "description": "The version the request addressed, by the instant it takes effect from.", + "example": "2027-01-01T00:00:00.000Z" + }, + "requested": { + "type": "string", + "description": "The instant the body asked for instead, canonicalized.", + "example": "2027-04-01T00:00:00.000Z" + } + } + } + } }, - "details": { + { + "type": "object", + "description": "A version write carrying a condition tuple other than the one its variant was\ncreated with. Create a second variant for the other situation.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VARIANT_CONDITIONS_IMMUTABLE" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "variant_id" + ], + "properties": { + "variant_id": { + "type": "string", + "description": "The variant whose conditions the write would have changed.", + "example": "var-46045" + } + } + } + } + }, + { + "type": "object", + "description": "An id in the request that cannot be used as a storage key: empty, longer than 128\ncharacters, or carrying a character outside letters, digits, `_`, `.`, `:` and `-`.\nEvery id the platform issues qualifies.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "IDENTIFIER_INVALID" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "field", + "reason" + ], + "properties": { + "field": { + "type": "string", + "description": "Which id could not be keyed by, named as the request names it.", + "enum": [ + "entity_id", + "variant_id" + ], + "example": "entity_id" + }, + "reason": { + "type": "string", + "description": "Which of the three checks the id failed, in prose.", + "example": "it carries a character this scheme does not admit" + } + } + } + } + }, + { + "type": "object", + "description": "A `valid_from` that is not one of the timestamp forms a version timeline can be\nsorted by. Wider ISO 8601 forms — a bare year, an ordinal date, `T24:00:00Z` — are\nrefused rather than interpreted.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VALID_FROM_INVALID" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "expected" + ], + "properties": { + "expected": { + "type": "string", + "description": "What a `valid_from` has to be, in prose.", + "example": "an RFC 3339 date, optionally with a time to at most millisecond precision and an optional UTC offset" + } + } + } + } + }, + { + "type": "object", + "description": "A value the store cannot hold: a non-finite number, one outside the table's numeric\nrange, or a key with no value. Send a value needing more precision than a JSON\nnumber carries as a decimal string, as `unit_amount_decimal` does.\n", + "required": [ + "code", + "details" + ], + "properties": { + "code": { + "type": "string", + "enum": [ + "VALUE_UNSTORABLE" + ] + }, + "details": { + "type": "object", + "additionalProperties": false, + "required": [ + "path", + "reason" + ], + "properties": { + "path": { + "type": "string", + "description": "Where the value sits, as a dotted path of the request's own keys, with array\nentries by index.\n", + "example": "values.tiers.0.unit_amount" + }, + "reason": { + "type": "string", + "description": "What about the value cannot be stored, in prose.", + "example": "the non-finite number Infinity" + } + } + } + } + }, + { "type": "object", - "additionalProperties": true, - "description": "Structured data about the failure, shaped by the accompanying `code`\n(e.g. the candidate variants of an `ambiguous-resolution`). Only present\nwhen the failure has structured data to report, and never without a `code`.\n" + "description": "A refusal the request validator raises, answered before any handler runs. The\nmessage says what to fix, and no code is sent — which is how a client tells this\nmember from the coded ones.\n", + "additionalProperties": false, + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + }, + "status": { + "type": "number" + }, + "cause": { + "type": "string" + }, + "error": { + "$ref": "#/components/schemas/ReportedError" + } + } } - } + ] } ] }, @@ -5382,6 +8699,10 @@ } } }, + "is_conditional": { + "description": "The flag for entities whose values vary by context. Resolve the values that apply with\n`POST /v1/conditional-pricing:resolve`.\n", + "type": "boolean" + }, "_availability_files": { "type": "array", "description": "Stores references to the availability files that define where this product is available.\nThese files are used when interacting with products via epilot Journeys, thought the AvailabilityCheck block.\n", @@ -6540,6 +9861,10 @@ false ] }, + "is_conditional": { + "description": "The flag for entities whose values vary by context. Resolve the values that apply with\n`POST /v1/conditional-pricing:resolve`.\n", + "type": "boolean" + }, "pricing_model": { "type": "string", "description": "Describes how to compute the price per period. Either `per_unit`, `tiered_graduated` or `tiered_volume`.\n- `per_unit` indicates that the fixed amount (specified in unit_amount or unit_amount_decimal) will be charged per unit in quantity\n- `tiered_graduated` indicates that the unit pricing will be computed using tiers attribute. The customer pays the price per unit in every range their purchase rises through.\n- `tiered_volume` indicates that the unit pricing will be computed using tiers attribute. The customer pays the same unit price for all purchased units.\n- `tiered_flatfee` While similar to tiered_volume, tiered flat fee charges for the same price (flat) for the entire range instead using the unit price to multiply the quantity.\n - `dynamic_tariff` indicates that the price is dynamically dependend on the (quarter)-hourly spot market price.\n- `external_getag` indicates that the price is influenced by aquisition fees provided by GetAG.\n", @@ -6860,6 +10185,10 @@ true ] }, + "is_conditional": { + "description": "The flag for entities whose values vary by context. Resolve the values that apply with\n`POST /v1/conditional-pricing:resolve`.\n", + "type": "boolean" + }, "_created_at": { "description": "The price creation date", "type": "string" @@ -10404,6 +13733,10 @@ "active": { "type": "boolean" }, + "is_conditional": { + "description": "The flag for entities whose values vary by context. Resolve the values that apply with\n`POST /v1/conditional-pricing:resolve`.\n", + "type": "boolean" + }, "requires_promo_code": { "type": "boolean", "description": "Whether the coupon requires a promo code to be applied"