changedOutput schema / properties / result / anyOf
Previous value: -[
- {
- "additionalProperties": false,
- "properties": {
- "_meta": {
- "additionalProperties": false,
- "description": "Canonical schema § 0.2 — present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == \"free\"`; absent on paid-tier responses.",
- "properties": {
- "deliverables": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.3 — R2 signed URLs (24h TTL).",
- "properties": {
- "docx_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "dxf_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "expires_at": {
- "minLength": 1,
- "type": "string"
- },
- "pdf_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "xlsx_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "expires_at"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "document_id": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "hint": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "issued_at": {
- "minLength": 1,
- "type": "string"
- },
- "output_mode": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``boq`` / ``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as \"capability missing\" (the box-culvert \"geometry\nbuilder isn't firing\" scare) rather than \"pared for size\": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) — both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\n— nothing is withheld, nothing to point at.",
- "properties": {
- "mode": {
- "enum": [
- "summary",
- "boq",
- "boq_with_backup"
- ],
- "type": "string"
- },
- "omitted_fields": {
- "items": {
- "type": "string"
- },
- "minItems": 1,
- "type": "array"
- },
- "retrieve_with": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "mode",
- "omitted_fields",
- "retrieve_with"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "rate_limit_remaining": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "request_id": {
- "minLength": 1,
- "type": "string"
- },
- "schema_version": {
- "const": "1.0.0",
- "default": "1.0.0",
- "type": "string"
- },
- "scope_boundary": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.6 — surfaces what this assembly produces vs not.",
- "properties": {
- "not_in_scope": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "produced": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "recommended_companions": {
- "anyOf": [
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "produced",
- "not_in_scope"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "tier": {
- "enum": [
- "free",
- "paid"
- ],
- "type": "string"
- },
- "tier_upgrade": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.7 — present on free-tier responses only.",
- "properties": {
- "available_tiers": {
- "items": {
- "additionalProperties": false,
- "description": "Canonical schema § 0.7 — single tier in the upgrade carousel.",
- "properties": {
- "billing": {
- "enum": [
- "one_off",
- "monthly",
- "annual"
- ],
- "type": "string"
- },
- "currency": {
- "enum": [
- "GBP",
- "SGD",
- "EUR",
- "USD",
- "CAD",
- "AUD",
- "NZD",
- "MYR"
- ],
- "type": "string"
- },
- "display_name": {
- "type": "string"
- },
- "price_local": {
- "type": "number"
- },
- "tier_slug": {
- "enum": [
- "7_day_pass",
- "solo",
- "studio",
- "practice"
- ],
- "type": "string"
- },
- "unlock_summary": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "tier_slug",
- "display_name",
- "price_local",
- "currency",
- "billing",
- "unlock_summary"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "current_tier": {
- "const": "free",
- "default": "free",
- "type": "string"
- },
- "pass_credit": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.7 — pass-credit upgrade hook.",
- "properties": {
- "amount_local": {
- "type": "number"
- },
- "applies_to": {
- "const": "solo_first_month",
- "default": "solo_first_month",
- "type": "string"
- },
- "currency": {
- "type": "string"
- },
- "redeemable_until": {
- "type": "string"
- }
- },
- "required": [
- "amount_local",
- "currency",
- "redeemable_until"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "pricing_url": {
- "default": "https://civilquants.com/pricing",
- "type": "string"
- }
- },
- "required": [
- "available_tiers"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "tos_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "upgrade_hint": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "warranty_disclaimer": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "request_id",
- "issued_at",
- "tier"
- ],
- "type": "object"
- },
- "data": {
- "anyOf": [
- {
- "additionalProperties": false,
- "properties": {
- "assembly_count": {
- "type": "integer"
- },
- "assembly_drawings": {
- "items": {
- "additionalProperties": false,
- "description": "One enabled assembly's drawing payload for the project recompute\nresponse (G.4.4b Step 2).\n\nMirrors the per-assembly drawing surface from\n``POST /api/assemblies/{slug}/compute`` (same ``DrawingRef`` shape,\nsame SVG renderer via ``build_drawing_ref``) so the project view's\ncontact-sheet centre pane renders identically to the single-assembly\ncalculator preview. ``drawing`` is nullable to stay backward-\ncompatible with assemblies that don't emit ``draw_entities`` (older\nshape); the few assemblies emitting an empty list still get a tiny\nplaceholder SVG so the UI never has to special-case absence.",
- "properties": {
- "assembly_id": {
- "type": "string"
- },
- "drawing": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Server-rendered SVG preview of the assembly geometry.\n\nPer G.6.3 / STATUS.md decision 6 (2026-05-19): one source of\ngeometry (`DrawEntity` list emitted by `Assembly.compute`), two\noutput paths (this SVG for inline preview, the `GET .../dxf`\nendpoint for the real CAD download). The browser displays\n`svg_b64` decoded inline; `viewbox` drives client zoom/pan\ncontrols without re-parsing the SVG.\n\n`svg_b64` is base64 of a UTF-8 SVG document with one `<g\nclass=\"cq-layer cq-layer-<name>\">` per layer. Styling defaults are\ninlined so the preview renders without an external stylesheet;\nfront-end CSS may override via the class names.",
- "properties": {
- "entity_count": {
- "description": "Number of DrawEntities rendered",
- "minimum": 0,
- "type": "integer"
- },
- "svg_b64": {
- "description": "Base64-encoded SVG document",
- "minLength": 1,
- "type": "string"
- },
- "unit_of_drawing": {
- "const": "m",
- "default": "m",
- "description": "Engine geometry is in metres. Surfaced here so the client never has to guess; if a future engine switches to mm this becomes the discriminator.",
- "type": "string"
- },
- "viewbox_height": {
- "description": "SVG viewBox height in engine units (m)",
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "viewbox_width": {
- "description": "SVG viewBox width in engine units (m)",
- "exclusiveMinimum": 0,
- "type": "number"
- },
- "viewbox_x": {
- "description": "SVG viewBox x in engine units (m)",
- "type": "number"
- },
- "viewbox_y": {
- "description": "SVG viewBox y in engine units (m)",
- "type": "number"
- }
- },
- "required": [
- "svg_b64",
- "viewbox_x",
- "viewbox_y",
- "viewbox_width",
- "viewbox_height",
- "entity_count"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "label": {
- "type": "string"
- },
- "position": {
- "type": "integer"
- },
- "slug": {
- "type": "string"
- }
- },
- "required": [
- "assembly_id",
- "slug",
- "label",
- "position"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "boqs_by_standard": {
- "additionalProperties": {
- "items": {
- "additionalProperties": false,
- "description": "Slim BoQ row for the recompute response. Matches the engine's own\n``BoQItem`` columns; rate / amount stay null per the freemium-MCP\npricing-is-yours discipline (schema § 1.3).",
- "properties": {
- "amount": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "code": {
- "type": "string"
- },
- "description": {
- "type": "string"
- },
- "group": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "nrm1_element": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "nrm1_group_element": {
- "anyOf": [
- {
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "nrm1_sub_element": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "quantity": {
- "minimum": 0,
- "type": "number"
- },
- "rate": {
- "anyOf": [
- {
- "type": "number"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "sub_group": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "unit": {
- "type": "string"
- }
- },
- "required": [
- "code",
- "description",
- "unit",
- "quantity"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "type": "object"
- },
- "procurement_summary": {
- "items": {
- "additionalProperties": false,
- "description": "One row of the project's procurement summary (G.4.4b Step 1).\n\nThe procurement summary is the standard-agnostic material rollup keyed\non ``(category, spec, unit)`` — distinct from ``boqs_by_standard`` (a\nmeasurement-standard projection) and identical across all four\nstandards by construction. Drives the right pane of\n``/workspace/[project_id]`` and the ``Procurement`` sheet of the\nproject XLSX (per launch spec § 3.4.2).",
- "properties": {
- "category": {
- "type": "string"
- },
- "quantity": {
- "minimum": 0,
- "type": "number"
- },
- "source_assemblies": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "spec": {
- "type": "string"
- },
- "unit": {
- "type": "string"
- }
- },
- "required": [
- "category",
- "spec",
- "quantity",
- "unit",
- "source_assemblies"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "project_id": {
- "type": "string"
- },
- "standards_rendered": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "work_item_count": {
- "type": "integer"
- }
- },
- "required": [
- "project_id",
- "standards_rendered",
- "assembly_count",
- "work_item_count",
- "boqs_by_standard",
- "procurement_summary",
- "assembly_drawings"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "error": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.4 — error payload returned in `MCPResponse.error`.",
- "properties": {
- "code": {
- "description": "Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) — clients use the flag to decide retry vs surface.",
- "enum": [
- "RATE_LIMIT_EXCEEDED",
- "TIER_INSUFFICIENT",
- "INVALID_INPUT",
- "SCHEMA_VERSION_MISMATCH",
- "SCHEMA_INVARIANT_VIOLATION",
- "UPSTREAM_TIMEOUT",
- "BACKEND_FAILURE",
- "IP_BLOCKED",
- "RESOURCE_NOT_FOUND",
- "RENDER_FAILURE",
- "OCR_LOW_CONFIDENCE",
- "MANUAL_REVIEW_REQUIRED",
- "ACCEPTANCE_REQUIRED",
- "INVALID_TOKEN"
- ],
- "type": "string"
- },
- "details": {
- "anyOf": [
- {
- "additionalProperties": true,
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "message": {
- "minLength": 1,
- "type": "string"
- },
- "recoverable": {
- "type": "boolean"
- },
- "retry_after_seconds": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "code",
- "message",
- "recoverable"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "_meta"
- ],
- "type": "object"
- },
- {
- "additionalProperties": false,
- "properties": {
- "_meta": {
- "additionalProperties": false,
- "description": "Canonical schema § 0.2 — present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == \"free\"`; absent on paid-tier responses.",
- "properties": {
- "deliverables": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.3 — R2 signed URLs (24h TTL).",
- "properties": {
- "docx_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "dxf_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "expires_at": {
- "minLength": 1,
- "type": "string"
- },
- "pdf_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "xlsx_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "expires_at"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "document_id": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "hint": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "issued_at": {
- "minLength": 1,
- "type": "string"
- },
- "output_mode": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``boq`` / ``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as \"capability missing\" (the box-culvert \"geometry\nbuilder isn't firing\" scare) rather than \"pared for size\": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) — both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\n— nothing is withheld, nothing to point at.",
- "properties": {
- "mode": {
- "enum": [
- "summary",
- "boq",
- "boq_with_backup"
- ],
- "type": "string"
- },
- "omitted_fields": {
- "items": {
- "type": "string"
- },
- "minItems": 1,
- "type": "array"
- },
- "retrieve_with": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "mode",
- "omitted_fields",
- "retrieve_with"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "rate_limit_remaining": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "request_id": {
- "minLength": 1,
- "type": "string"
- },
- "schema_version": {
- "const": "1.0.0",
- "default": "1.0.0",
- "type": "string"
- },
- "scope_boundary": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.6 — surfaces what this assembly produces vs not.",
- "properties": {
- "not_in_scope": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "produced": {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- "recommended_companions": {
- "anyOf": [
- {
- "items": {
- "type": "string"
- },
- "type": "array"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "produced",
- "not_in_scope"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "tier": {
- "enum": [
- "free",
- "paid"
- ],
- "type": "string"
- },
- "tier_upgrade": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.7 — present on free-tier responses only.",
- "properties": {
- "available_tiers": {
- "items": {
- "additionalProperties": false,
- "description": "Canonical schema § 0.7 — single tier in the upgrade carousel.",
- "properties": {
- "billing": {
- "enum": [
- "one_off",
- "monthly",
- "annual"
- ],
- "type": "string"
- },
- "currency": {
- "enum": [
- "GBP",
- "SGD",
- "EUR",
- "USD",
- "CAD",
- "AUD",
- "NZD",
- "MYR"
- ],
- "type": "string"
- },
- "display_name": {
- "type": "string"
- },
- "price_local": {
- "type": "number"
- },
- "tier_slug": {
- "enum": [
- "7_day_pass",
- "solo",
- "studio",
- "practice"
- ],
- "type": "string"
- },
- "unlock_summary": {
- "minLength": 1,
- "type": "string"
- }
- },
- "required": [
- "tier_slug",
- "display_name",
- "price_local",
- "currency",
- "billing",
- "unlock_summary"
- ],
- "type": "object"
- },
- "type": "array"
- },
- "current_tier": {
- "const": "free",
- "default": "free",
- "type": "string"
- },
- "pass_credit": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.7 — pass-credit upgrade hook.",
- "properties": {
- "amount_local": {
- "type": "number"
- },
- "applies_to": {
- "const": "solo_first_month",
- "default": "solo_first_month",
- "type": "string"
- },
- "currency": {
- "type": "string"
- },
- "redeemable_until": {
- "type": "string"
- }
- },
- "required": [
- "amount_local",
- "currency",
- "redeemable_until"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "pricing_url": {
- "default": "https://civilquants.com/pricing",
- "type": "string"
- }
- },
- "required": [
- "available_tiers"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "tos_url": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "upgrade_hint": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "warranty_disclaimer": {
- "anyOf": [
- {
- "type": "string"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "request_id",
- "issued_at",
- "tier"
- ],
- "type": "object"
- },
- "data": {
- "default": null,
- "title": "Data"
- },
- "error": {
- "anyOf": [
- {
- "additionalProperties": false,
- "description": "Canonical schema § 0.4 — error payload returned in `MCPResponse.error`.",
- "properties": {
- "code": {
- "description": "Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) — clients use the flag to decide retry vs surface.",
- "enum": [
- "RATE_LIMIT_EXCEEDED",
- "TIER_INSUFFICIENT",
- "INVALID_INPUT",
- "SCHEMA_VERSION_MISMATCH",
- "SCHEMA_INVARIANT_VIOLATION",
- "UPSTREAM_TIMEOUT",
- "BACKEND_FAILURE",
- "IP_BLOCKED",
- "RESOURCE_NOT_FOUND",
- "RENDER_FAILURE",
- "OCR_LOW_CONFIDENCE",
- "MANUAL_REVIEW_REQUIRED",
- "ACCEPTANCE_REQUIRED",
- "INVALID_TOKEN"
- ],
- "type": "string"
- },
- "details": {
- "anyOf": [
- {
- "additionalProperties": true,
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- },
- "message": {
- "minLength": 1,
- "type": "string"
- },
- "recoverable": {
- "type": "boolean"
- },
- "retry_after_seconds": {
- "anyOf": [
- {
- "minimum": 0,
- "type": "integer"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "code",
- "message",
- "recoverable"
- ],
- "type": "object"
- },
- {
- "type": "null"
- }
- ],
- "default": null
- }
- },
- "required": [
- "_meta"
- ],
- "type": "object"
- }
-]New value: +[
+ {
+ "additionalProperties": false,
+ "properties": {
+ "_meta": {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.2 — present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == \"free\"`; absent on paid-tier responses.",
+ "properties": {
+ "deliverables": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.3 — R2 signed URLs (24h TTL).",
+ "properties": {
+ "docx_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "dxf_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "expires_at": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "pdf_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "xlsx_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "expires_at"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "document_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "hint": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "issued_at": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "output_mode": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as \"capability missing\" (the box-culvert \"geometry\nbuilder isn't firing\" scare) rather than \"pared for size\": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) — both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\n— nothing is withheld, nothing to point at.",
+ "properties": {
+ "mode": {
+ "enum": [
+ "summary",
+ "material_schedule",
+ "boq",
+ "boq_with_backup"
+ ],
+ "type": "string"
+ },
+ "omitted_fields": {
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "retrieve_with": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "mode",
+ "omitted_fields",
+ "retrieve_with"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "rate_limit_remaining": {
+ "anyOf": [
+ {
+ "minimum": 0,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "request_id": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "schema_version": {
+ "const": "1.0.0",
+ "default": "1.0.0",
+ "type": "string"
+ },
+ "scope_boundary": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.6 — surfaces what this assembly produces vs not.",
+ "properties": {
+ "not_in_scope": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "produced": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "recommended_companions": {
+ "anyOf": [
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "produced",
+ "not_in_scope"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "tier": {
+ "enum": [
+ "free",
+ "paid"
+ ],
+ "type": "string"
+ },
+ "tier_upgrade": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.7 — present on free-tier responses only.",
+ "properties": {
+ "available_tiers": {
+ "items": {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.7 — single tier in the upgrade carousel.",
+ "properties": {
+ "billing": {
+ "enum": [
+ "one_off",
+ "monthly",
+ "annual"
+ ],
+ "type": "string"
+ },
+ "currency": {
+ "enum": [
+ "GBP",
+ "SGD",
+ "EUR",
+ "USD",
+ "CAD",
+ "AUD",
+ "NZD",
+ "MYR"
+ ],
+ "type": "string"
+ },
+ "display_name": {
+ "type": "string"
+ },
+ "price_local": {
+ "type": "number"
+ },
+ "tier_slug": {
+ "enum": [
+ "7_day_pass",
+ "solo",
+ "studio",
+ "practice"
+ ],
+ "type": "string"
+ },
+ "unlock_summary": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "tier_slug",
+ "display_name",
+ "price_local",
+ "currency",
+ "billing",
+ "unlock_summary"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "current_tier": {
+ "const": "free",
+ "default": "free",
+ "type": "string"
+ },
+ "pass_credit": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.7 — pass-credit upgrade hook.",
+ "properties": {
+ "amount_local": {
+ "type": "number"
+ },
+ "applies_to": {
+ "const": "solo_first_month",
+ "default": "solo_first_month",
+ "type": "string"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "redeemable_until": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "amount_local",
+ "currency",
+ "redeemable_until"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "pricing_url": {
+ "default": "https://civilquants.com/pricing",
+ "type": "string"
+ }
+ },
+ "required": [
+ "available_tiers"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "tos_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "upgrade_hint": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "warranty_disclaimer": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "request_id",
+ "issued_at",
+ "tier"
+ ],
+ "type": "object"
+ },
+ "data": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "properties": {
+ "assembly_count": {
+ "type": "integer"
+ },
+ "assembly_drawings": {
+ "items": {
+ "additionalProperties": false,
+ "description": "One enabled assembly's drawing payload for the project recompute\nresponse (G.4.4b Step 2).\n\nMirrors the per-assembly drawing surface from\n``POST /api/assemblies/{slug}/compute`` (same ``DrawingRef`` shape,\nsame SVG renderer via ``build_drawing_ref``) so the project view's\ncontact-sheet centre pane renders identically to the single-assembly\ncalculator preview. ``drawing`` is nullable to stay backward-\ncompatible with assemblies that don't emit ``draw_entities`` (older\nshape); the few assemblies emitting an empty list still get a tiny\nplaceholder SVG so the UI never has to special-case absence.",
+ "properties": {
+ "assembly_id": {
+ "type": "string"
+ },
+ "drawing": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Server-rendered SVG preview of the assembly geometry.\n\nPer G.6.3 / STATUS.md decision 6 (2026-05-19): one source of\ngeometry (`DrawEntity` list emitted by `Assembly.compute`), two\noutput paths (this SVG for inline preview, the `GET .../dxf`\nendpoint for the real CAD download). The browser displays\n`svg_b64` decoded inline; `viewbox` drives client zoom/pan\ncontrols without re-parsing the SVG.\n\n`svg_b64` is base64 of a UTF-8 SVG document with one `<g\nclass=\"cq-layer cq-layer-<name>\">` per layer. Styling defaults are\ninlined so the preview renders without an external stylesheet;\nfront-end CSS may override via the class names.",
+ "properties": {
+ "entity_count": {
+ "description": "Number of DrawEntities rendered",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "svg_b64": {
+ "description": "Base64-encoded SVG document",
+ "minLength": 1,
+ "type": "string"
+ },
+ "unit_of_drawing": {
+ "const": "m",
+ "default": "m",
+ "description": "Engine geometry is in metres. Surfaced here so the client never has to guess; if a future engine switches to mm this becomes the discriminator.",
+ "type": "string"
+ },
+ "viewbox_height": {
+ "description": "SVG viewBox height in engine units (m)",
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "viewbox_width": {
+ "description": "SVG viewBox width in engine units (m)",
+ "exclusiveMinimum": 0,
+ "type": "number"
+ },
+ "viewbox_x": {
+ "description": "SVG viewBox x in engine units (m)",
+ "type": "number"
+ },
+ "viewbox_y": {
+ "description": "SVG viewBox y in engine units (m)",
+ "type": "number"
+ }
+ },
+ "required": [
+ "svg_b64",
+ "viewbox_x",
+ "viewbox_y",
+ "viewbox_width",
+ "viewbox_height",
+ "entity_count"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "label": {
+ "type": "string"
+ },
+ "position": {
+ "type": "integer"
+ },
+ "slug": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "assembly_id",
+ "slug",
+ "label",
+ "position"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "boqs_by_standard": {
+ "additionalProperties": {
+ "items": {
+ "additionalProperties": false,
+ "description": "Slim BoQ row for the recompute response. Matches the engine's own\n``BoQItem`` columns; rate / amount stay null per the freemium-MCP\npricing-is-yours discipline (schema § 1.3).",
+ "properties": {
+ "amount": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "code": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "group": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "nrm1_element": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "nrm1_group_element": {
+ "anyOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "nrm1_sub_element": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "quantity": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "rate": {
+ "anyOf": [
+ {
+ "type": "number"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "sub_group": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "unit": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "code",
+ "description",
+ "unit",
+ "quantity"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "type": "object"
+ },
+ "procurement_summary": {
+ "items": {
+ "additionalProperties": false,
+ "description": "One row of the project's procurement summary (G.4.4b Step 1).\n\nThe procurement summary is the standard-agnostic material rollup keyed\non ``(category, spec, unit)`` — distinct from ``boqs_by_standard`` (a\nmeasurement-standard projection) and identical across all four\nstandards by construction. Drives the right pane of\n``/workspace/[project_id]`` and the ``Procurement`` sheet of the\nproject XLSX (per launch spec § 3.4.2).",
+ "properties": {
+ "category": {
+ "type": "string"
+ },
+ "quantity": {
+ "minimum": 0,
+ "type": "number"
+ },
+ "source_assemblies": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "spec": {
+ "type": "string"
+ },
+ "unit": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "category",
+ "spec",
+ "quantity",
+ "unit",
+ "source_assemblies"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "project_id": {
+ "type": "string"
+ },
+ "standards_rendered": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "work_item_count": {
+ "type": "integer"
+ }
+ },
+ "required": [
+ "project_id",
+ "standards_rendered",
+ "assembly_count",
+ "work_item_count",
+ "boqs_by_standard",
+ "procurement_summary",
+ "assembly_drawings"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "error": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.4 — error payload returned in `MCPResponse.error`.",
+ "properties": {
+ "code": {
+ "description": "Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) — clients use the flag to decide retry vs surface.",
+ "enum": [
+ "RATE_LIMIT_EXCEEDED",
+ "TIER_INSUFFICIENT",
+ "INVALID_INPUT",
+ "SCHEMA_VERSION_MISMATCH",
+ "SCHEMA_INVARIANT_VIOLATION",
+ "UPSTREAM_TIMEOUT",
+ "BACKEND_FAILURE",
+ "IP_BLOCKED",
+ "RESOURCE_NOT_FOUND",
+ "RENDER_FAILURE",
+ "OCR_LOW_CONFIDENCE",
+ "MANUAL_REVIEW_REQUIRED",
+ "ACCEPTANCE_REQUIRED",
+ "INVALID_TOKEN"
+ ],
+ "type": "string"
+ },
+ "details": {
+ "anyOf": [
+ {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "message": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "recoverable": {
+ "type": "boolean"
+ },
+ "retry_after_seconds": {
+ "anyOf": [
+ {
+ "minimum": 0,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "code",
+ "message",
+ "recoverable"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "_meta"
+ ],
+ "type": "object"
+ },
+ {
+ "additionalProperties": false,
+ "properties": {
+ "_meta": {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.2 — present on every MCPResponse.\n\nRequired fields: `schema_version`, `request_id`, `issued_at`, `tier`.\nThe free-tier-only fields (`upgrade_hint`, `tos_url`, `warranty_disclaimer`,\n`tier_upgrade`, `rate_limit_remaining`) are populated by the middleware\nwhen `tier == \"free\"`; absent on paid-tier responses.",
+ "properties": {
+ "deliverables": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.3 — R2 signed URLs (24h TTL).",
+ "properties": {
+ "docx_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "dxf_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "expires_at": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "pdf_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "xlsx_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "expires_at"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "document_id": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "hint": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "issued_at": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "output_mode": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Surfaces what a trimmed ``output_mode`` withheld from ``data``.\n\nA trimmed mode (``summary`` / ``material_schedule`` / ``boq`` /\n``boq_with_backup``) withholds\nalready-computed fields to keep the chat payload small. The withheld value\nreads to a client agent as \"capability missing\" (the box-culvert \"geometry\nbuilder isn't firing\" scare) rather than \"pared for size\": ``drawing`` and\n``audit_trail`` appear as ``null``, ``boq_rows`` as an empty list ``[]``\n(its type forbids ``null``) — both indistinguishable from a genuine absent\nresult. This names the withheld fields and the exact mode that brings each\nback, so the value is unambiguous. Absent on the default ``full_json`` mode\n— nothing is withheld, nothing to point at.",
+ "properties": {
+ "mode": {
+ "enum": [
+ "summary",
+ "material_schedule",
+ "boq",
+ "boq_with_backup"
+ ],
+ "type": "string"
+ },
+ "omitted_fields": {
+ "items": {
+ "type": "string"
+ },
+ "minItems": 1,
+ "type": "array"
+ },
+ "retrieve_with": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "mode",
+ "omitted_fields",
+ "retrieve_with"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "rate_limit_remaining": {
+ "anyOf": [
+ {
+ "minimum": 0,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "request_id": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "schema_version": {
+ "const": "1.0.0",
+ "default": "1.0.0",
+ "type": "string"
+ },
+ "scope_boundary": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.6 — surfaces what this assembly produces vs not.",
+ "properties": {
+ "not_in_scope": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "produced": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "recommended_companions": {
+ "anyOf": [
+ {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "produced",
+ "not_in_scope"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "tier": {
+ "enum": [
+ "free",
+ "paid"
+ ],
+ "type": "string"
+ },
+ "tier_upgrade": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.7 — present on free-tier responses only.",
+ "properties": {
+ "available_tiers": {
+ "items": {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.7 — single tier in the upgrade carousel.",
+ "properties": {
+ "billing": {
+ "enum": [
+ "one_off",
+ "monthly",
+ "annual"
+ ],
+ "type": "string"
+ },
+ "currency": {
+ "enum": [
+ "GBP",
+ "SGD",
+ "EUR",
+ "USD",
+ "CAD",
+ "AUD",
+ "NZD",
+ "MYR"
+ ],
+ "type": "string"
+ },
+ "display_name": {
+ "type": "string"
+ },
+ "price_local": {
+ "type": "number"
+ },
+ "tier_slug": {
+ "enum": [
+ "7_day_pass",
+ "solo",
+ "studio",
+ "practice"
+ ],
+ "type": "string"
+ },
+ "unlock_summary": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "tier_slug",
+ "display_name",
+ "price_local",
+ "currency",
+ "billing",
+ "unlock_summary"
+ ],
+ "type": "object"
+ },
+ "type": "array"
+ },
+ "current_tier": {
+ "const": "free",
+ "default": "free",
+ "type": "string"
+ },
+ "pass_credit": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.7 — pass-credit upgrade hook.",
+ "properties": {
+ "amount_local": {
+ "type": "number"
+ },
+ "applies_to": {
+ "const": "solo_first_month",
+ "default": "solo_first_month",
+ "type": "string"
+ },
+ "currency": {
+ "type": "string"
+ },
+ "redeemable_until": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "amount_local",
+ "currency",
+ "redeemable_until"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "pricing_url": {
+ "default": "https://civilquants.com/pricing",
+ "type": "string"
+ }
+ },
+ "required": [
+ "available_tiers"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "tos_url": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "upgrade_hint": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "warranty_disclaimer": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "request_id",
+ "issued_at",
+ "tier"
+ ],
+ "type": "object"
+ },
+ "data": {
+ "default": null,
+ "title": "Data"
+ },
+ "error": {
+ "anyOf": [
+ {
+ "additionalProperties": false,
+ "description": "Canonical schema § 0.4 — error payload returned in `MCPResponse.error`.",
+ "properties": {
+ "code": {
+ "description": "Canonical schema § 0.5 catalogue.\n\nEach member maps to a documented `recoverable` flag (see\n`IS_RECOVERABLE`) — clients use the flag to decide retry vs surface.",
+ "enum": [
+ "RATE_LIMIT_EXCEEDED",
+ "TIER_INSUFFICIENT",
+ "INVALID_INPUT",
+ "SCHEMA_VERSION_MISMATCH",
+ "SCHEMA_INVARIANT_VIOLATION",
+ "UPSTREAM_TIMEOUT",
+ "BACKEND_FAILURE",
+ "IP_BLOCKED",
+ "RESOURCE_NOT_FOUND",
+ "RENDER_FAILURE",
+ "OCR_LOW_CONFIDENCE",
+ "MANUAL_REVIEW_REQUIRED",
+ "ACCEPTANCE_REQUIRED",
+ "INVALID_TOKEN"
+ ],
+ "type": "string"
+ },
+ "details": {
+ "anyOf": [
+ {
+ "additionalProperties": true,
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ },
+ "message": {
+ "minLength": 1,
+ "type": "string"
+ },
+ "recoverable": {
+ "type": "boolean"
+ },
+ "retry_after_seconds": {
+ "anyOf": [
+ {
+ "minimum": 0,
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "code",
+ "message",
+ "recoverable"
+ ],
+ "type": "object"
+ },
+ {
+ "type": "null"
+ }
+ ],
+ "default": null
+ }
+ },
+ "required": [
+ "_meta"
+ ],
+ "type": "object"
+ }
+]