Developer docs menu

Errors

How the Quotometry APIs report problems: one problem document shape, stable codes, and the difference between a failed request and an unpriceable part.

This page explains how the buyer API and the merchant API report problems, and how your integration should respond to each kind. Read it before you write error handling: a line that needs review is a normal answer, not an error, and the two must be handled differently.

The problem document

Every non-2xx response is an RFC 9457 problem document with the media type application/problem+json:

{
  "type": "https://docs.quotometry.app/errors#invalid_request",
  "title": "Request is not valid",
  "status": 422,
  "code": "invalid_request",
  "issues": [
    { "path": "machines[0].params.travel_factor", "code": "out_of_range", "severity": "error",
      "message": "must be between 0 and 1" }
  ]
}
FieldTypeAlways presentDescription
typestringYesA stable identifier for the code, not the address of this page.
titlestringYesA short, human-readable summary. Prose: do not match on it.
statusintegerYesThe HTTP status, repeated.
codestringYesThe stable wire name. Match on this. It never changes.
detailstringNoMore about this occurrence, for example which plan feature was refused. Prose.
issuesarrayNoField-level problems, each with path, code, severity and message. path uses the same syntax as the console.
incident_idstringNoPresent on a 500. Quote it when you contact support.

A 500 response carries an incident_id and nothing else about the failure. The detail is in our logs, not in a response a stranger can read.

Three kinds of “no”

It matters which one you are looking at.

A failed request is a 4xx or 5xx response with a problem document: you sent something the API cannot act on, you are not allowed to do it, or you asked too often.

An unpriceable line is a 200 response. The call succeeded, but the line has a state of review or blocked, and its reasons explain why: oversize, no_compatible_machine, over_review_qty, a DFM code and so on. This is the normal way a shop says “we need to look at this one”.

A DFM verdict is advice attached to a part: a thin wall, an unsupported overhang, a tiny hole. Depending on the shop’s rules it may only inform the buyer, add a charge, block the line or send it to review.

Common codes

The codes you will meet most often while integrating:

CodeStatusMeaningWhat to do
unauthorized401The key or session is missing or not valid.Check the key you send.
forbidden403The credential is valid but not for this. detail says why, for example origin not allowed for this widget.For an origin, add the page’s origin to the widget’s allowed origins.
plan_forbids403Your plan does not include this (merchant API). detail names what.Change plan, or remove what goes over it.
not_found404The id is wrong, or belongs to another shop.Check the id.
invalid_request422The request failed validation.Read issues; each has a path.
rate_limited429A rate limit refused the call.Wait Retry-After seconds. See rate limits.
stale_etag412Someone else saved the draft first (merchant API).Read the draft again and re-apply your change.
quote_expired409The quote’s validity period has ended.Price again and save a new quote.
price_changed409The configuration was republished between the quote and the order.Show the new price and ask the buyer to confirm.
file_not_ready409The file’s upload has not completed (merchant API file download).Try again once the upload has completed.
file_purged409Retention has removed the file.The buyer must upload it again.
too_large413The body or file is larger than the endpoint accepts.Send a smaller file.

Why price_changed exists

When an order is placed, Quotometry checks that the quote’s price still stands. If the shop republished its configuration in between, the API refuses the order rather than quietly charging a different amount from the one the buyer agreed to.

The full registry

Every issue code, line-state reason, DFM code, breakdown line id, problem code and event type is kept in one file in the repository, because these names are a contract and a contract needs one home: docs/agent-docs/api/errors.md.

Next steps