Zum Inhalt springen

Upsert a delta product batch

PUT
/v1/ingest/products
curl --request PUT \
--url http://localhost:8080/v1/ingest/products \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: example' \
--header 'X-Antares-Environment-Fingerprint: example' \
--data '{ "schemaVersion": 1, "channel": "example", "lang": "example", "defaultCurrency": "EUR", "currencies": [ "EUR" ], "priceContexts": [ { "ctx": "c0193d1ae60d471e7d0712efda7de10115a", "label": "example", "customerGroupId": "example", "ruleIds": [ "example" ], "tierBoundaries": [ 1 ] } ], "products": [ { "id": "example", "sku": "example", "ean": "example", "name": "example", "description": "example", "url": "example", "images": [ { "src": "example", "thumb280": "example", "thumb560": "example", "alt": "example" } ], "manufacturer": { "id": "example", "name": "example", "number": "example" }, "categories": [ { "id": "example", "name": "example", "path": "example" } ], "prices": { "additionalProperty": { "gross": 1, "net": 1, "list": 1 } }, "priceRange": { "additionalProperty": { "min": 1, "max": 1 } }, "purchasePrice": 1, "priceContexts": { "additionalProperty": { "prices": { "additionalProperty": { "gross": 1, "net": 1, "list": 1 } }, "priceRange": { "additionalProperty": { "min": 1, "max": 1 } }, "tiers": { "additionalProperty": [ { "qty": 1, "gross": 1, "net": 1 } ] } } }, "hasTierPrices": true, "stock": { "available": 1, "isCloseout": true }, "properties": { "additionalProperty": [ "example" ] }, "technicalData": "example", "searchKeywords": [ "example" ], "variant": { "count": 1, "axes": [ "example" ], "skus": [ "example" ], "eans": [ "example" ] }, "flags": { "active": true, "isNew": true, "topseller": true }, "releasedAt": "2026-04-15T12:00:00Z", "custom": {} } ] }'

Delta upsert against the live alias. While a full run is open for the same (channel, lang) the same documents are additionally written to the shadow collection, which is what makes a full rebuild lossless. No batch commits partially: one failing product fails the whole request with one errors[] entry per product.

X-Antares-Environment-Fingerprint
required
string
>= 16 characters <= 128 characters

SHA-256 over the shop’s APP_URL plus its platform version. APP_URL lives in .env and is not carried by a database dump, which is exactly why it is the discriminator between a production install and a clone of it.

Idempotency-Key
required
string
>= 8 characters <= 128 characters

Caller-generated key. Replaying the same key with the same body replays the stored response; replaying it with a different body is 409 idempotency_conflict.

Media typeapplication/json
object
schemaVersion
required
integer
Allowed value: 1
channel
required

The Antares channel key, for example b2c-de. Must resolve to a (channel, lang) collection for the authenticated shop.

string
>= 1 characters <= 100 characters
lang
required
string
/^[a-z]{2}-[A-Z]{2}$/
defaultCurrency
required

The channel’s own currency. Must equal the channel’s stored default currency; a mismatch is 422 validation_failed. Margin, the widget’s fallback display and the default sort field are all expressed in it, which is why a product without a price in it is rejected rather than indexed at zero.

string
/^[A-Z]{3}$/
currencies
required

Every currency the sales channel assigns, defaultCurrency first. The connector is the source of truth here: the API reconciles the channel’s stored currency assignment to this list on every envelope, so assigning a currency in the shop is enough to have it indexed.

Array<string>
>= 1 items <= 20 items unique items
priceContexts

The registry of the channel’s price contexts — not the batch’s. It may be sent unchanged on every batch; the API upserts it idempotently. A product may only reference a context present here or already registered for the channel. A context that no envelope has mentioned for 30 days and that no document carries is pruned.

Array<object>
<= 64 items

One entry of the channel’s price-context registry, carrying the structured input of the fingerprint rather than the canonical string. The API rebuilds the canonical string from these fields, hashes it, and compares the result to ctx; a mismatch fails the whole batch with price_context_fingerprint_mismatch. That comparison is the only mechanism that catches a PHP↔Go disagreement on the day it appears instead of six months later in a support ticket about wrong prices.

object
ctx
required

The fingerprint the connector computed. The literal default must not appear here: the default context is implicit and always exists.

string
/^c[0-9]{2}[0-9a-f]{32}$/
label
required

Merchant-facing description of the situation, for example Händler B2B · Preisliste 2026. Panel only, never reaches the widget, and deliberately not part of the fingerprint so renaming a price list does not orphan every materialised price field.

string
>= 1 characters <= 120 characters
customerGroupId

The raw platform customer-group id, as the platform spells it. Omit it when the platform has no customer groups. The API normalises it (trim, ASCII-only case fold, remove every -) before hashing, so the dashed and undashed spellings of the same UUID are the same context.

string
<= 128 characters
ruleIds

The raw platform ids of the price rules that matched for this situation, in any order. The API normalises, deduplicates and sorts them, so the platform’s priority ordering — which is meaningless for identity — never reaches the fingerprint.

Array<string>
<= 32 items
tierBoundaries

Quantity thresholds contributed by this context’s own quantity-conditioned price rules, which make the matching rule set itself quantity-dependent. The value 1 is dropped because quantity 1 is always implied. Not the per-product price ladder: that is per (product, rule), varies from product to product, and lives in PriceContext.tiers as a value inside the context.

Array<integer>
<= 16 items
products
required
Array<object>
>= 1 items <= 500 items

The neutral product schema. The platform ends at this boundary; nothing downstream ever sees a Shopware concept. Server-derived fields (margin_pct, margin_norm, boost_conv, boost_sales, weighted_score, embedding, price_val_*, price_sort_*, pc_*) must never be sent and are rejected by additionalProperties: false.

object
id
required

Stable platform id. The document id in the index.

string
>= 1 characters <= 255 characters
sku
string
<= 255 characters
ean
string
<= 64 characters
name
required
string
>= 1 characters <= 500 characters
description

Plain text, already stripped of markup by the connector.

string
<= 2000 characters
url
required

SEO path relative to the channel domain, per (channel, lang).

string format: uri-reference
images
Array<object>
<= 20 items
object
src
required
string format: uri-reference
thumb280

280 px thumbnail, used by the instant dropdown.

string format: uri-reference
thumb560

560 px thumbnail, used by the result grid.

string format: uri-reference
alt
string
manufacturer
object
id
required
string
name
required
string
number

Manufacturer part number. Indexed for infix matching.

string
categories
Array<object>
<= 100 items
object
id
required
string
name
required
string
path
required

Breadcrumb path, >-separated, used as the facet’s display value.

string
prices
required

Default-context price per ISO currency. Every currency the sales channel assigns and the product actually prices is carried, so the storefront can switch currency without a reindex. A missing defaultCurrency entry rejects the product; a missing secondary currency simply drops the product from that currency’s results. A currency the channel does not assign is 422 currency_not_indexed.

object
>= 1 properties
key
additional properties
object
gross
required
number
net
required
number
list

Strike-through reference price. Omit when the product is not on sale.

number
priceRange

The variant “from–to” gross span per currency. Every currency present in prices must have an entry, because the API indexes one facet range per priced currency and a price without its range would silently vanish from the price facet. For a product without variants min == max == gross.

object
>= 1 properties
key
additional properties
object
min
required
number
max
required
number
purchasePrice

Net purchase price in the shop’s house currency. The only margin input the connector supplies. Stored unindexed, used to derive marginNorm, and never present in any response to a public credential.

number
priceContexts

Materialised customer prices keyed by price-context fingerprint. The literal default is reserved and rejected here — the default prices are prices and priceRange. Only contexts that deviate from the default are sent. A context whose prices equal the default in every currency must be omitted; this is the sizing rule the whole feature depends on, because in a normal catalogue almost every product costs the same for almost every context and omitting them is what keeps documents inside the per-tenant RAM budget. At most 64 contexts and at most 128 (context × currency) families per product, or the product is rejected with price_context_budget_exceeded. The API returns at most the single context a request proves entitlement to, and never the map itself.

object
<= 64 properties
key
additional properties

One context’s deviating prices for one product. It may cover a subset of the product’s currencies; a currency absent here simply has no context price and falls back to the default for that currency. Pricing a currency the product’s default context does not price rejects the product, because such a price has nothing to fall back to and would leak through the default field family.

object
prices
required

Prices per upper-case ISO 4217 currency.

object
>= 1 properties
key
additional properties
object
gross
required
number
net
required
number
list

Strike-through reference price. Omit when the product is not on sale.

number
priceRange

Defaults to the product’s own priceRange when omitted.

object
>= 1 properties
key
additional properties
object
min
required
number
max
required
number
tiers

Quantity ladders per upper-case ISO currency, ascending by qty, at most 32 rungs. These are the per-product ladders and are values inside the context, never part of its identity.

object
key
additional properties
Array<object>
<= 32 items

Quantity-scaled price. qty is the lowest quantity at which the price applies.

object
qty
required
integer
>= 1
gross
required
number
net
required
number
hasTierPrices

Display hint for the widget’s tier_prices badge, derived by the connector from “any context carries tiers for this product”.

boolean
stock
required
object
available
required

Units on hand. Thresholded into in_stock/low/out before serving.

integer
isCloseout
required

The product cannot be ordered beyond the available quantity, so zero stock means unavailable rather than backorderable.

boolean
properties
required

The shop’s own property axes, keyed by normalised name, for example {"farbe": ["blau"]}. Each becomes a properties.<name> facet.

object
key
additional properties
Array<string>
technicalData

Flattened technical specification text, indexed for infix matching.

string
<= 10000 characters
searchKeywords

Merchant-maintained additional search terms.

Array<string>
<= 100 items
variant
required

Parent-level strategy: one document per parent, carrying the identifiers and axes of all its variants so a variant SKU still finds the parent. Channels that need one document per variant set indexVariantsSeparately.

object
count
required
integer
axes
required
Array<string>
skus
required
Array<string>
eans
required
Array<string>
flags
required
object
active
required

false is not a validation failure: the id is moved to the delete list of the same request and removed from the live and shadow collections.

boolean
isNew
required
boolean
topseller
required
boolean
releasedAt

Release date, the input to the novelty ranking signal.

string format: date-time
custom

Connector-specific passthrough. Indexed as-is and never interpreted.

object
key
additional properties
any

Batch validated and upserted.

Media typeapplication/json
object
accepted
required
integer
rejected
required
integer
errors
Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
Examplegenerated
{
"accepted": 1,
"rejected": 1,
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

contract_validation_failed — the OpenAPI request validator rejected the request before the handler ran — or invalid_request when the body is unreadable or is not valid JSON for the declared operation.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

unauthorized — the credential is missing, malformed, unknown or revoked. For /v1/admin this also covers an actor JWS that fails signature, exp or kid verification, and a kid that no key in the panel’s JWKS matches.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

quota_exceeded — a hard cap was reached (sandbox plan, or a trial past its grace window); paid plans get the soft cap instead, which is 200 plus X-Antares-Quota: exceeded. Or plan_feature_unavailable — the organization’s resolved entitlements do not include the requested feature.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

One of index_run_active (a full run is already open for this channel and language), index_run_closed (batch or commit against a committed or aborted run), batch_out_of_order (batchIndex is not lastBatchIndex + 1 and not an exact replay), batch_conflict (the batch could not be recorded idempotently), idempotency_conflict (the same Idempotency-Key with a different body) or environment_mismatch.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

request_too_large — the body exceeds this endpoint’s byte limit. Also returned for chunked bodies without Content-Length once the limit is passed mid-stream.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

One of validation_failed (envelope-level failure, or one or more products failed; errors[] carries productIndex and no partial batch is committed), channel_not_found (the (channel, lang) pair is not mapped for this shop), currency_not_indexed (a product prices a currency the channel does not assign), price_context_fingerprint_mismatch (the API recomputed the fingerprint from the registry entry’s structured input and got a different value — the PHP↔Go drift alarm, which fails the whole batch), price_context_budget_exceeded (more than 64 contexts or more than 128 context × currency families on one product) or document_count_sanity_failed (a commit would drop the live document count below 50 % of the previous run; the old collection stays live).

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

One of rate_limit_exceeded, authentication_admission_full (the pre-auth admission guard for large connector bodies), connector_admission_full (this sk already occupies its single large-body slot) or request_admission_full (global large-body validation slots exhausted). All three admission codes are retryable after a short backoff.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}
Retry-After
integer
>= 1

Seconds to wait before retrying.

internal_error — unhandled failure. detail is always generic; the cause goes to the log with a correlation id.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

search_backend_unavailable — Typesense failed an ingest, alias, synonym or collection operation.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}

One of idempotency_unavailable (the idempotency advisory lock could not be taken), index_lock_unavailable (the per-channel advisory lock could not be taken), analytics_unavailable (ClickHouse rejected a synchronous, business-critical write) or service_unavailable. All are retryable.

Media typeapplication/problem+json

RFC 9457 problem details. type is always https://api.antares.commergy.de/problems/{code} and is built in exactly one place. type, code and title are stable and never localised; only detail is localised, and only where the registry marks the audience as merchant.

object
type
required

Absolute problem type URI. Stable identifier, never localised.

string format: uri-reference
title
required

Stable English summary of the problem type.

string
status
required

The HTTP status code, repeated in the body.

integer
>= 400 <= 599
detail

Human-readable explanation of this occurrence. The only localised field; may be German or English depending on Accept-Language.

string
instance

The request path this occurrence relates to.

string format: uri-reference
code

The registry code, for example price_context_token_expired. This is what a client branches on; never branch on title or detail.

string
errors

Present only for per-item validation failures, above all ingest batches.

Array<object>
object
field
required

Dotted path of the offending field inside the request body, for example prices.CHF.gross.

string
message
required

What is wrong with it, in English.

string
productIndex

0-based index into the request’s products array. Present only for ingest batches, and the only way to map an error back to a product without echoing it.

integer
key
additional properties
any
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"code": "example",
"errors": [
{
"field": "example",
"message": "example",
"productIndex": 1
}
]
}