REST API (v2)

Errors

The shared error shape and canonical code list.

Errors

Every error response — REST or MCP — carries the same { ok: false, errors: [...] } shape. code is stable; message and fix_hint are human-readable.

Shape

{
  "ok": false,
  "errors": [
    {
      "code": "element_not_found",
      "message": "Element 'missing' not found in ai@2026-04-16-beta.",
      "path": "elements[0].element_id",
      "fix_hint": "Use GET /api/v2/schemas/:version/elements to enumerate available element ids."
    }
  ]
}
FieldRequiredMeaning
codeyesStable machine-readable code from the table below.
messageyesHuman-readable diagnostic.
pathnoJSON path into the caller's payload (e.g. elements[3].category_id).
fix_hintnoShort actionable instruction.

Adding new code values is additive; renaming or removing is a breaking change (guarded by snapshot fixtures in the repo).

Codes

Transport-level (HTTP status mirrors the code)

CodeHTTPMeaning
bad_request400Malformed input — version path param, query params, request body, or invalid cursor.
not_found404Unknown version, element, symbol, variant, or shape.
payload_too_large413Request body exceeds the configured byte limit.
rate_limited429Client exceeded the rate-limit bucket. Retry-After header indicates the wait.
timeout504Request exceeded the per-route wall-clock budget.
upstream_error502Schema-store (R2) read failed.
internal_error500Unexpected server error.

Semantic — surfaced in 200 bodies

CodeRaised byMeaning
parse_errorPOST /validate, MCP validate / renderDatachain shape failed Zod validation. path locates the offending field.
element_not_foundMCP get_elements (per-id), MCP get_icon_url, MCP get_elementElement not present in the version.
element_ids_too_manyMCP get_elements>100 unique ids after dedupe.
unknown_versionMCP toolsManifest missing for the resolved version.
unknown_variantMCP get_icon_urlVariant not in the element's icon_variants. fix_hint lists valid variants.
invalid_argumentsMCP toolsArgument failed the tool's Zod input schema.
Semantic validator codes/validate, render_datachain, validate_datachainShape-valid but semantically wrong — required categories missing, placement invalid, cardinality violated, etc.

Rate limiting

Read endpoints share one bucket; POST /validate uses a dedicated tighter bucket. Setting DTPR-Client: <name> opts your traffic into a per-client bucket. On exceed:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60

{
  "ok": false,
  "errors": [
    {
      "code": "rate_limited",
      "message": "Rate limit exceeded.",
      "fix_hint": "Wait 60 seconds or set `DTPR-Client` for a dedicated bucket."
    }
  ]
}

See also

Copyright © 2026