Error Responses & Problem Types

When a request to the Seller API fails, the API returns a consistent, machine-readable error body alongside the HTTP status code. This page explains the shape of that body, the type field (the problem type), and—most importantly—how to handle it so that an integration keeps working as the API evolves.

The type field carries a problem type: a URI that identifies the specific kind of problem that occurred, independent of the HTTP status code. The remaining fields (message and errors) are Seller API conventions that add human-readable and field-level detail.

The Error Body

Every error response shares the same structure:

{
    "type": "/problems/validation-error",
    "message": "Validation Failed",
    "errors": [
        {
            "field": "callbackUrl",
            "message": "not valid"
        }
    ]
}
Field Type Description
type string (URI reference) An identifier for the kind of problem that occurred. Match on it to drive error handling — see Handling problem types below.
message string A short, human-readable summary of what went wrong. Intended for logs and developers — do not parse it programmatically.
errors array of { field, message } Optional. Field-level details, mainly for validation errors. Empty ([]) when there are no per-field details.

The HTTP status code remains the first signal of what happened (4xx = client error, 5xx = server error). The type field adds a finer-grained identifier on top of it.

Handling problem types

Handling problem types comes down to a single idea that keeps an integration working as the API grows:

Act on the problem types relevant to the integration. For every other type — including unrecognised ones and about:blank — fall back to the rest of the response: the HTTP status code as the primary signal, with the message and errors fields for additional context.

In practice, this means maintaining a single list — the problem types the integration handles — and nothing more. There is no need to classify types into categories, track which ones are stable, or keep an exhaustive list of every type the API might return.

What we guarantee

Two promises make this approach safe to rely on:

  1. A problem type's meaning never changes. Once a type is published, its meaning is fixed — for example, /problems/validation-error will always carry the same meaning. Published types are never renamed or repurposed.
  2. New, more specific types may appear over time. A situation that returns a broad type today may start returning a new, narrower type in the future, providing more precise, actionable information. As long as the HTTP status code is used as the fallback for types that are not explicitly handled, this is never a breaking change — the new type can be adopted whenever convenient, and until then it behaves exactly as before.

This is the reason the approach matters. Treating a broad type such as /problems/bad-request as a permanent, exhaustive contract carries a risk: when a dedicated type is later introduced for one of the cases it used to cover, that handling silently stops matching. Falling back to the HTTP status code for anything not explicitly handled avoids this entirely.

Match on type, not on message

Use type—not the message text—to drive logic. The wording of message may be refined at any time and is meant for humans reading logs. Two different problems can also share the same HTTP status code (e.g. several distinct 400s); the type is what tells them apart.

When there is no specific problem type: about:blank

Not every error has a dedicated problem type. When a response does not carry a more specific one, type is set to about:blank:

{
    "type": "about:blank",
    "message": "Resource not found",
    "errors": []
}

about:blank carries no semantics beyond the HTTP status code. It is not a special case: it should be handled like any other type that is not explicitly matched — base the response on the HTTP status code, with the message and errors fields for additional context.

Getting more detail (dereferencing)

type values are relative URIs on purpose (e.g. /problems/validation-error). They stay identical whether a request is made against the playground or production — only the base URL changes, not the identifier. To read the human-readable documentation for a specific problem, resolve the type against the Seller API base URI — that is, append the type value to:

https://sellerapi.kaufland.com

For example, given this error response:

{
    "type": "/problems/units/default-warehouse-not-found",
    "message": "No default warehouse is configured for this seller account",
    "errors": []
}

open the resolved URL in a browser:

https://sellerapi.kaufland.com/problems/units/default-warehouse-not-found

This links directly to the Problem Types reference, scrolled to that exact problem, where its description and recommended next steps are documented. Dereferencing is intended only when a developer wants the full context behind a problem — client code should match on the type string and must not dereference it automatically at runtime to make decisions.

Problem Type Reference

The table below lists the broad, cross-cutting problem types the API can return. These act as a fallback: when a specific error case does not (yet) have a dedicated type, one of these generic types is returned instead. Over time some of these error cases gain their own dedicated problem type (tied to a specific resource — orders, returns, warehouses, tickets, …), which then carries more precise information than the generic fallback.

There is no need to memorise which types are broad and which are dedicated — handling them works the same way either way. The complete, up-to-date catalogue, including every dedicated type and the endpoints that return it, is on the Problem Types reference page.

Problem type Typical status Meaning What to do
/problems/bad-request 400 The request is invalid or malformed. Review the request against the API semantics and check message for details.
/problems/validation-error 400 The request contains invalid or malformed details. Check that every property matches the documented schema. Inspect message and errors.
/problems/missing-or-invalid-request-header 400 A mandatory request header is missing or malformed. See the required headers documentation and check message.
/problems/unauthorized 401 The request lacks valid authentication information. Ensure the credentials are valid; check message for details.
/problems/forbidden 403 Access to the requested resource is not authorised. Verify the account's permissions; check message for why access is restricted.
/problems/not-found 404 The requested resource was not found. Ensure the correct identifier is used.
/problems/duplicate-action 409 The action was already performed and cannot be repeated. No action needed — the operation already took effect.
/problems/action-not-allowed 422 The requested action cannot be performed on this entity in its current state. Check message for details on why the action is not permitted.
/problems/storefront-not-configured 400 The requested storefront is not configured for the account. Configure the storefront in the Seller Portal, or contact support.
/problems/invalid-credentials 401 No account matched the provided credentials. Ensure correct and valid credentials are used.
/problems/corrupted-signature 401 The request signature could not be verified. Re-check the request-signing process and that every step is implemented correctly.
/problems/inactive-account 403 The account being accessed is no longer active. Contact the responsible seller manager for more information.
/problems/server-error 500 The server encountered an unexpected error. Retry later; if it persists, contact support.
/problems/service-unavailable 503 The service is temporarily unavailable. Retry with exponential backoff. If it persists, contact support.

Best Practices

  • Fall back to the rest of the response for any type not explicitly handled. Act on the types that are relevant to the integration, and for unrecognised, new, or about:blank types rely on the HTTP status code, with the message and errors fields for additional context. This is what keeps an integration working as new types are introduced.
  • Match on type, not on message. Treat message as developer-facing text that may change.
  • Use the HTTP status code for transport-level decisions (retry on 5xx, stop on 4xx), and the type for application-level decisions.
  • Ignore unknown fields. New fields may be added to the error body over time; parsers should tolerate them.
  • Do not treat the current set of types as exhaustive. New, more specific types can appear for situations that previously returned a broad one; falling back to the HTTP status code for types that are not explicitly handled covers this gracefully.