{
  "components": {
    "schemas": {
      "AccessConfig": {
        "additionalProperties": false,
        "description": "A workspace's access-control setting, chosen once at creation.\n\n``labels = []`` is the default and means **no filtering at all** — no\nclassification pass at ingestion, no filter clause at retrieval, and\n``Coverage`` reports nothing. A workspace that does not need document-level\naccess control should not pay for a classification that always returns the\nsame answer.\n\nCoverage reporting is always strict: whenever the gate withholds candidates,\nthe response says so in counts and label names. A silently narrowed answer\nis the failure mode this platform exists to prevent, so there is no opt-out.",
        "properties": {
          "default_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Applied when the classifier cannot decide. Required whenever labels is non-empty.",
            "title": "Default Label"
          },
          "labels": {
            "items": {
              "$ref": "#/components/schemas/AccessLabel"
            },
            "maxItems": 16,
            "title": "Labels",
            "type": "array"
          }
        },
        "title": "AccessConfig",
        "type": "object"
      },
      "AccessLabel": {
        "additionalProperties": false,
        "description": "One label in a workspace's unordered list.",
        "properties": {
          "description": {
            "description": "This string IS the classifier's prompt.",
            "title": "Description",
            "type": "string"
          },
          "name": {
            "maxLength": 64,
            "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "description"
        ],
        "title": "AccessLabel",
        "type": "object"
      },
      "AccessLabelCatalogEntry": {
        "additionalProperties": false,
        "description": "One reusable label in the tenant catalog.",
        "properties": {
          "access_label_id": {
            "format": "uuid",
            "title": "Access Label Id",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "maxLength": 2000,
            "minLength": 1,
            "title": "Description",
            "type": "string"
          },
          "name": {
            "maxLength": 64,
            "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
            "title": "Name",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          }
        },
        "required": [
          "access_label_id",
          "name",
          "description",
          "created_at",
          "updated_at"
        ],
        "title": "AccessLabelCatalogEntry",
        "type": "object"
      },
      "AccessLabelSource": {
        "description": "Which mechanism produced a document's label.\n\nThe ``default_label`` fallback records as ``inherited``, so an audit can\ntell a real classification from a fallback.",
        "enum": [
          "inherited",
          "classified",
          "mirrored"
        ],
        "title": "AccessLabelSource",
        "type": "string"
      },
      "ActivityDetail": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "description": "The tool input being described.",
            "title": "Name",
            "type": "string"
          },
          "value": {
            "description": "A bounded, displayable value of the input.",
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "name",
          "value"
        ],
        "title": "ActivityDetail",
        "type": "object"
      },
      "ActivitySnapshot": {
        "additionalProperties": false,
        "properties": {
          "activities": {
            "description": "Observed work in chronological order.",
            "items": {
              "$ref": "#/components/schemas/AgentActivity"
            },
            "title": "Activities",
            "type": "array"
          },
          "cursor": {
            "default": "0-0",
            "description": "Opaque replay cursor for subscribing after this snapshot.",
            "title": "Cursor",
            "type": "string"
          },
          "incomplete": {
            "default": false,
            "description": "Whether some activity could not be captured or recovered.",
            "title": "Incomplete",
            "type": "boolean"
          },
          "job_id": {
            "description": "The job whose agent work is shown.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Authoritative job state, independent of the trace's availability."
          },
          "type": {
            "const": "snapshot",
            "default": "snapshot",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "job_id",
          "status"
        ],
        "title": "ActivitySnapshot",
        "type": "object"
      },
      "AgentActivity": {
        "additionalProperties": false,
        "properties": {
          "attempt": {
            "description": "Execution attempt; a retry never appends to an earlier attempt's thinking.",
            "title": "Attempt",
            "type": "integer"
          },
          "details": {
            "description": "Allowlisted tool inputs, suitable for an expanded view.",
            "items": {
              "$ref": "#/components/schemas/ActivityDetail"
            },
            "title": "Details",
            "type": "array"
          },
          "display_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Human-facing description of a recognized tool operation.",
            "title": "Display Name"
          },
          "execution_id": {
            "description": "Agent execution that produced this activity.",
            "title": "Execution Id",
            "type": "string"
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the activity finished, when known.",
            "title": "Finished At"
          },
          "id": {
            "description": "Stable identity of this activity within the job.",
            "title": "Id",
            "type": "string"
          },
          "kind": {
            "description": "Whether this is model thinking, a tool, model commentary, or the answer as the agent writes it. An answer is a draft while running, accepted once completed, replaced by a retry once superseded, and handed over when it is an automatic search's fact answer the agent was then asked to settle; the job's result is the published answer.",
            "enum": [
              "thinking",
              "tool",
              "message",
              "answer"
            ],
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "description": "Tool name or agent activity label.",
            "title": "Name",
            "type": "string"
          },
          "revision": {
            "default": 0,
            "description": "Increasing version of this activity, used to ignore duplicated or older updates.",
            "title": "Revision",
            "type": "integer"
          },
          "started_at": {
            "description": "When the activity was first observed.",
            "format": "date-time",
            "title": "Started At",
            "type": "string"
          },
          "status": {
            "description": "The observed state of this activity. Interrupted and superseded activities are incomplete. A handed-over answer is complete but is not the job's: fact search wrote it before the automatic search handed the question to the agent, whose activities follow it.",
            "enum": [
              "running",
              "completed",
              "failed",
              "retrying",
              "interrupted",
              "superseded",
              "handed_over"
            ],
            "title": "Status",
            "type": "string"
          },
          "step_id": {
            "description": "Model request or tool call this activity belongs to.",
            "title": "Step Id",
            "type": "string"
          },
          "text": {
            "default": "",
            "description": "Bounded thinking, commentary, or tool result text.",
            "title": "Text",
            "type": "string"
          },
          "truncated": {
            "default": false,
            "description": "Whether the activity exceeded the retained text budget.",
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "execution_id",
          "step_id",
          "attempt",
          "kind",
          "name",
          "status",
          "started_at"
        ],
        "title": "AgentActivity",
        "type": "object"
      },
      "AnswerCacheInfo": {
        "additionalProperties": false,
        "description": "How a search answer relates to the workspace's semantic answer cache.\n\nPresent only on a run that served a previously derived answer instead of\nderiving a new one. Everything else on the result — the evidences, the\nreasoning, the tool-call trace, the receipts — describes that ORIGINAL\nderivation, which is what this block exists to say out loud: the answer was\ncomputed once, for a question near enough to this one, under an identical\nscope and an identical access gate, and re-checked against the workspace\nbefore it was handed back. A result with no ``cache`` block was derived by\nthe run that returned it.",
        "properties": {
          "cached_at": {
            "description": "When the answer was originally derived. Read it as the age of the evidence: the workspace may have changed since, which is what the re-check below is for.",
            "format": "date-time",
            "title": "Cached At",
            "type": "string"
          },
          "served_from_cache": {
            "description": "True when this result was re-served from a previously derived answer rather than computed by this run. Always true where this block appears at all.",
            "title": "Served From Cache",
            "type": "boolean"
          },
          "source_job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The job whose run originally derived this answer. Null when that job's row has since been reaped — the answer outlives the record of the run that produced it.",
            "title": "Source Job Id"
          },
          "verified_at": {
            "description": "When this run re-checked the cached answer's citations against the workspace and accepted them. Always this run's own time — a cached answer is never served unchecked.",
            "format": "date-time",
            "title": "Verified At",
            "type": "string"
          }
        },
        "required": [
          "served_from_cache",
          "cached_at",
          "verified_at"
        ],
        "title": "AnswerCacheInfo",
        "type": "object"
      },
      "AppliedDecisionWire": {
        "additionalProperties": false,
        "description": "What one reading did with one stored human decision.\n\nPublished because the three outcomes are three different things for a\nreviewer to do next, and an answer that silently had no effect is the one\nstate a review surface must never show as settled.",
        "properties": {
          "detail": {
            "default": "",
            "description": "Why, when the outcome is not 'applied'.",
            "title": "Detail",
            "type": "string"
          },
          "key": {
            "description": "The binding slot, or the parse signature — the same key the decision was written under.",
            "title": "Key",
            "type": "string"
          },
          "kind": {
            "description": "Which kind of reviewable thing it was about.",
            "enum": [
              "role_slot",
              "parse_signature",
              "period_mapping",
              "encoding_mapping"
            ],
            "title": "Kind",
            "type": "string"
          },
          "outcome": {
            "description": "'applied': folded in. 'orphaned': this reading has nothing open under that key, usually because the data now settles it. 'conflict': the question stands but the answer is not one of the alternatives it offers, so re-answering it is what clears this.",
            "enum": [
              "applied",
              "orphaned",
              "conflict"
            ],
            "title": "Outcome",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "key",
          "outcome"
        ],
        "title": "AppliedDecisionWire",
        "type": "object"
      },
      "ArtifactOutputDetail": {
        "additionalProperties": false,
        "description": "A live ``derived_file`` output plus short-lived presigned URLs for its bytes.\n\nSearch-index and knowledge-graph outputs are not downloadable this way —\ntheir ``path`` is an opaque index key, not an object in the workspace store.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "download_url": {
            "description": "Time-limited presigned GET URL that saves the derivative's bytes to disk.",
            "title": "Download Url",
            "type": "string"
          },
          "download_url_expires_at": {
            "description": "When the presigned URLs stop being valid.",
            "format": "date-time",
            "title": "Download Url Expires At",
            "type": "string"
          },
          "generation": {
            "description": "The file version this output was produced from.",
            "title": "Generation",
            "type": "integer"
          },
          "kind": {
            "$ref": "#/components/schemas/ArtifactOutputKind"
          },
          "output_id": {
            "format": "uuid",
            "title": "Output Id",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "preview_url": {
            "description": "Time-limited presigned GET URL that a browser renders inline.",
            "title": "Preview Url",
            "type": "string"
          }
        },
        "required": [
          "output_id",
          "kind",
          "path",
          "generation",
          "created_at",
          "download_url",
          "preview_url",
          "download_url_expires_at"
        ],
        "title": "ArtifactOutputDetail",
        "type": "object"
      },
      "ArtifactOutputKind": {
        "description": "Where a derivation landed, for the deletion cascade.",
        "enum": [
          "opensearch_doc",
          "kg_document",
          "derived_file"
        ],
        "title": "ArtifactOutputKind",
        "type": "string"
      },
      "ArtifactOutputMember": {
        "additionalProperties": false,
        "description": "One object inside a derived-output folder, with short-lived fetch URLs.\n\nA recording's ``frames/`` output is registered as one folder, not one row\nper JPEG (root ``AGENTS.md`` → media lane). This is how a caller browses\nthat folder's members without the ledger carrying thousands of rows: the\nobjects are listed from storage on demand and presigned inline.",
        "properties": {
          "download_url": {
            "description": "Time-limited presigned GET URL that saves the member to disk.",
            "title": "Download Url",
            "type": "string"
          },
          "file_name": {
            "description": "The member's base name.",
            "title": "File Name",
            "type": "string"
          },
          "path": {
            "description": "Workspace-relative path of the member object.",
            "title": "Path",
            "type": "string"
          },
          "preview_url": {
            "description": "Time-limited presigned GET URL that a browser renders inline.",
            "title": "Preview Url",
            "type": "string"
          },
          "size_bytes": {
            "description": "Object size in bytes.",
            "title": "Size Bytes",
            "type": "integer"
          }
        },
        "required": [
          "path",
          "file_name",
          "size_bytes",
          "download_url",
          "preview_url"
        ],
        "title": "ArtifactOutputMember",
        "type": "object"
      },
      "ArtifactOutputMembersPage": {
        "additionalProperties": false,
        "description": "A page of the objects inside a derived-output folder.\n\n``total_count`` is the whole folder; ``members`` is the requested window,\nso a large ``frames/`` folder streams into the console a page at a time\ninstead of presigning thousands of URLs at once.",
        "properties": {
          "download_url_expires_at": {
            "description": "When the presigned URLs stop being valid.",
            "format": "date-time",
            "title": "Download Url Expires At",
            "type": "string"
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/ArtifactOutputMember"
            },
            "title": "Members",
            "type": "array"
          },
          "total_count": {
            "description": "Objects in the folder, across all pages.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "members",
          "total_count",
          "download_url_expires_at"
        ],
        "title": "ArtifactOutputMembersPage",
        "type": "object"
      },
      "ArtifactOutputRef": {
        "additionalProperties": false,
        "description": "One thing a source file produced outside the file store.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "generation": {
            "description": "The file version this output was produced from.",
            "title": "Generation",
            "type": "integer"
          },
          "kind": {
            "$ref": "#/components/schemas/ArtifactOutputKind"
          },
          "output_id": {
            "format": "uuid",
            "title": "Output Id",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "output_id",
          "kind",
          "path",
          "generation",
          "created_at"
        ],
        "title": "ArtifactOutputRef",
        "type": "object"
      },
      "ArtifactRowRun": {
        "additionalProperties": false,
        "description": "One inclusive 0-based run of matched rows in the pageable artifact.",
        "properties": {
          "end": {
            "description": "Last matched row of the run, 0-based and inclusive.",
            "title": "End",
            "type": "integer"
          },
          "start": {
            "description": "First matched row of the run, 0-based and inclusive.",
            "title": "Start",
            "type": "integer"
          }
        },
        "required": [
          "start",
          "end"
        ],
        "title": "ArtifactRowRun",
        "type": "object"
      },
      "ArtifactRowsPage": {
        "additionalProperties": false,
        "description": "One page of rows from a tabular workspace artifact.\n\nRows are returned in file order, so ``start_row`` is both the request\noffset and the file row number of ``rows[0]`` — callers can label each\nrow with its source row number without another lookup.",
        "properties": {
          "columns": {
            "items": {
              "$ref": "#/components/schemas/QueryTableColumn"
            },
            "title": "Columns",
            "type": "array"
          },
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "rows": {
            "items": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "title": "Rows",
            "type": "array"
          },
          "start_row": {
            "title": "Start Row",
            "type": "integer"
          },
          "total_rows": {
            "title": "Total Rows",
            "type": "integer"
          }
        },
        "required": [
          "path",
          "start_row",
          "limit",
          "total_rows",
          "columns",
          "rows"
        ],
        "title": "ArtifactRowsPage",
        "type": "object"
      },
      "AudioRange": {
        "additionalProperties": false,
        "properties": {
          "end_ms": {
            "title": "End Ms",
            "type": "integer"
          },
          "kind": {
            "const": "audio_range",
            "default": "audio_range",
            "title": "Kind",
            "type": "string"
          },
          "start_ms": {
            "title": "Start Ms",
            "type": "integer"
          }
        },
        "required": [
          "start_ms",
          "end_ms"
        ],
        "title": "AudioRange",
        "type": "object"
      },
      "AutoConfirmation": {
        "additionalProperties": false,
        "properties": {
          "candidate_index": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Validated nomination chosen for automatic measurement, if any.",
            "title": "Candidate Index"
          },
          "reason": {
            "description": "Why discovery confirmed the package or requires review.",
            "title": "Reason",
            "type": "string"
          },
          "selection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Confirmed source selection used by the follow-up run.",
            "title": "Selection Id"
          }
        },
        "required": [
          "reason"
        ],
        "title": "AutoConfirmation",
        "type": "object"
      },
      "AutoDecisionWire": {
        "additionalProperties": false,
        "properties": {
          "choice": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Offered alternative selected or suggested.",
            "title": "Choice"
          },
          "confidence": {
            "anyOf": [
              {
                "enum": [
                  "high",
                  "medium",
                  "low"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Model confidence before validation.",
            "title": "Confidence"
          },
          "detail": {
            "default": "",
            "description": "Validation reason or deterministic evidence.",
            "title": "Detail",
            "type": "string"
          },
          "outcome": {
            "description": "Checkpoint outcome after deterministic validation; a nominated journal identity was sent to complete-population measurement, which alone can accept it.",
            "enum": [
              "accepted_sole",
              "accepted_model",
              "suggested",
              "refused",
              "unanswered",
              "nominated"
            ],
            "title": "Outcome",
            "type": "string"
          },
          "rationale": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Model explanation of its choice.",
            "title": "Rationale"
          },
          "slot": {
            "description": "Binding question addressed by the automatic checkpoint.",
            "title": "Slot",
            "type": "string"
          }
        },
        "required": [
          "slot",
          "outcome"
        ],
        "title": "AutoDecisionWire",
        "type": "object"
      },
      "AutomaticAgentResult": {
        "additionalProperties": false,
        "description": "The automatic search agent's answer, plus its published catalog selection when it made one.\n\n``answer`` is a complete source-level deep-search result (citations, SQL\nreceipts, confidence). ``catalog`` is present when the agent answered with a\nmetadata-catalog query: the server re-executed it authoritatively, and its\n``next_cursor`` pages through this job.",
        "properties": {
          "answer": {
            "$ref": "#/components/schemas/DeepSearchV2Result",
            "description": "The agent's grounded answer."
          },
          "catalog": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FilteredSearchResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The catalog entries the agent selected, when it answered with a catalog query."
          },
          "result_type": {
            "const": "automatic_agent",
            "default": "automatic_agent",
            "description": "Identifies an automatic search agent result.",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "answer"
        ],
        "title": "AutomaticAgentResult",
        "type": "object"
      },
      "AutomaticLlmRouter": {
        "additionalProperties": false,
        "description": "An LLM chose the route. Its explanation is the routing's ``reason``.",
        "properties": {
          "kind": {
            "const": "llm",
            "default": "llm",
            "title": "Kind",
            "type": "string"
          }
        },
        "title": "AutomaticLlmRouter",
        "type": "object"
      },
      "AutomaticNaceDmRouter": {
        "additionalProperties": false,
        "description": "NaceDM, the decision model, chose the route by scoring how likely the query needs the agent.",
        "properties": {
          "decision_point": {
            "description": "The agent runs when ``p_agent`` is at or above this; fact search runs below it.",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Decision Point",
            "type": "number"
          },
          "kind": {
            "const": "nacedm",
            "default": "nacedm",
            "title": "Kind",
            "type": "string"
          },
          "p_agent": {
            "anyOf": [
              {
                "maximum": 1.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "NaceDM's probability that the query needs the investigating agent rather than one fact-search pass; 1 - p_agent is the probability that fact search settles it. Null when the request was too long for NaceDM to score, which routes to the agent.",
            "title": "P Agent"
          }
        },
        "required": [
          "p_agent",
          "decision_point"
        ],
        "title": "AutomaticNaceDmRouter",
        "type": "object"
      },
      "AutomaticRequestedRouter": {
        "additionalProperties": false,
        "description": "No router ran: the request's ``mode`` named the route, or the workspace had no ingested files.",
        "properties": {
          "kind": {
            "const": "requested",
            "default": "requested",
            "title": "Kind",
            "type": "string"
          }
        },
        "title": "AutomaticRequestedRouter",
        "type": "object"
      },
      "AutomaticSearchJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "intelligent_search",
            "default": "intelligent_search",
            "description": "Automatic search orchestration job.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AutomaticSearchResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "AutomaticSearchJob",
        "type": "object"
      },
      "AutomaticSearchRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /workspaces/{workspace_id}/automatic-search``.\n\nSingle-shot query, optional context, and folder and file scope. In ``auto`` mode the fixed\nrouter selects fact search or the automatic search agent before retrieval, and a fact search\nthat cannot settle the question hands the query to the agent, while a \"not found\" over\nmaterial it read whole stands; ``fact`` and ``agent`` run that route directly, with no\nhand-over. Execution settings are resolved by the service; this\nroute has no effort or clarification controls.",
        "properties": {
          "context": {
            "anyOf": [
              {
                "maxLength": 20000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional free-form background for the model. It does not change access or retrieval scope.",
            "title": "Context"
          },
          "mode": {
            "default": "auto",
            "description": "Which route answers. `auto` (the default) lets the router choose fact search for a focused lookup or the agent for anything that needs investigating; when it chooses fact search and fact search cannot settle the question, the agent answers instead, but a 'not found' over material it read whole stands. `fact` runs fact search and `agent` runs the agent, with no routing step and no hand-over. The agent opens on what a navigator over the workspace's files, sections and pages located for the query, then reads, queries tables and locates again until the question is answered; on a workspace in a bring-your-own bucket or customer storage, it opens on what a search of the workspace found and explores with search and file listings instead.",
            "enum": [
              "auto",
              "fact",
              "agent"
            ],
            "title": "Mode",
            "type": "string"
          },
          "output_schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A JSON Schema (Draft 2020-12, object root, local non-recursive `$ref` only, no `pattern`, `patternProperties` or `unevaluated*`) the answer must follow. When set, the agent writes `answer` as JSON text conforming to it, the run checks that and asks the agent to correct a mismatch, and the result carries the parsed value in `structured_answer`. A field the source does not state comes back null, whatever type the schema gives it. Explanation goes to `reasoning` where the result has one, and evidences are unchanged. If the answer still misses the schema, the run succeeds with `answer` as written and `structured_answer` null. Omit for a prose answer.",
            "title": "Output Schema"
          },
          "path_prefix": {
            "anyOf": [
              {
                "maxLength": 1024,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Narrow the search to this workspace subtree. Omit to search the whole workspace.",
            "title": "Path Prefix"
          },
          "paths": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 1024,
                  "minLength": 1,
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Scope the run to exactly these uploaded files. Every retrieval leg and agent tool sees only these files and the content ingested from them, so nothing else can be read or cited. Each entry names an uploaded source file (never a folder — scope folders with path_prefix; the two add up, so the run covers the folder's files plus these). No limit on how many. Unknown or inaccessible paths are refused up front.",
            "title": "Paths"
          },
          "query": {
            "description": "The question to answer from the workspace. Surrounding whitespace is stripped; a blank query is refused.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "top_k": {
            "anyOf": [
              {
                "maximum": 50.0,
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How many evidences fact search returns, best first; omitted means 6, and the ceiling is 50. A cap on the citation list, not on how much is read. Applies only when fact search answers: the agent chooses its own evidences.",
            "title": "Top K"
          }
        },
        "required": [
          "query"
        ],
        "title": "AutomaticSearchRequest",
        "type": "object"
      },
      "AutomaticSearchResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "description": "The selected pipeline's native result, preserving citations, completeness, and pagination.",
            "discriminator": {
              "mapping": {
                "automatic_agent": "#/components/schemas/AutomaticAgentResult",
                "deep_search_v2": "#/components/schemas/DeepSearchV2Result",
                "filtered_search": "#/components/schemas/FilteredSearchResult",
                "intelligent_search": "#/components/schemas/IntelligentSearchResult"
              },
              "propertyName": "result_type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/IntelligentSearchResult"
              },
              {
                "$ref": "#/components/schemas/AutomaticAgentResult"
              },
              {
                "$ref": "#/components/schemas/DeepSearchV2Result"
              },
              {
                "$ref": "#/components/schemas/FilteredSearchResult"
              }
            ],
            "title": "Output"
          },
          "output_job_id": {
            "description": "Job that owns the output's receipts and cursors; use it to read retained result rows.",
            "format": "uuid",
            "title": "Output Job Id",
            "type": "string"
          },
          "result_type": {
            "const": "automatic_search",
            "default": "automatic_search",
            "description": "Identifies an automatic search result.",
            "title": "Result Type",
            "type": "string"
          },
          "routing": {
            "$ref": "#/components/schemas/AutomaticSearchRouting",
            "description": "The selected pipeline and the router's explanation."
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SearchLlmUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "Complete combined LLM usage when available; null when any stage is unmetered."
          }
        },
        "required": [
          "output",
          "output_job_id",
          "routing"
        ],
        "title": "AutomaticSearchResult",
        "type": "object"
      },
      "AutomaticSearchRouting": {
        "additionalProperties": false,
        "properties": {
          "delegated_wall_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Wall time spent preparing and running the native deep or filtered job.",
            "title": "Delegated Wall Ms"
          },
          "fact_wall_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Wall time spent running fact search, when selected.",
            "title": "Fact Wall Ms"
          },
          "final": {
            "description": "The pipeline that produced the returned output. It differs from `selected` only in `auto` mode, when the router chose fact search, fact search could not settle the question, and the agent answered instead.",
            "enum": [
              "fact",
              "agent",
              "deep",
              "filtered"
            ],
            "title": "Final",
            "type": "string"
          },
          "reason": {
            "description": "The router's explanation of its decision, or why no router ran.",
            "title": "Reason",
            "type": "string"
          },
          "router": {
            "description": "Which router decided, and what it measured: an LLM (its explanation is ``reason``), NaceDM (its probability and decision point), or `requested` when no router ran: the request's `mode` was `fact` or `agent`, or the workspace had no ingested files. Results routed before this field existed read as the LLM.",
            "discriminator": {
              "mapping": {
                "llm": "#/components/schemas/AutomaticLlmRouter",
                "nacedm": "#/components/schemas/AutomaticNaceDmRouter",
                "requested": "#/components/schemas/AutomaticRequestedRouter"
              },
              "propertyName": "kind"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/AutomaticLlmRouter"
              },
              {
                "$ref": "#/components/schemas/AutomaticNaceDmRouter"
              },
              {
                "$ref": "#/components/schemas/AutomaticRequestedRouter"
              }
            ],
            "title": "Router"
          },
          "router_model": {
            "description": "The model used to choose the search pipeline; `none` when no router ran.",
            "title": "Router Model",
            "type": "string"
          },
          "router_wall_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Wall time spent selecting the initial route.",
            "title": "Router Wall Ms"
          },
          "selected": {
            "description": "The route the router chose, the one the request's `mode` named, or `fact` when nothing was searched: the workspace had no ingested files, or the query asked for nothing that a document contains.",
            "enum": [
              "fact",
              "agent",
              "deep",
              "filtered"
            ],
            "title": "Selected",
            "type": "string"
          }
        },
        "required": [
          "selected",
          "final",
          "reason",
          "router_model"
        ],
        "title": "AutomaticSearchRouting",
        "type": "object"
      },
      "BasisWire": {
        "additionalProperties": false,
        "description": "One amount basis the package states, and how well it balances.",
        "properties": {
          "balances_per_journal": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Share of journals netting to zero measured on this basis specifically.",
            "title": "Balances Per Journal"
          },
          "credit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The credit column of the pair, where the basis is a pair.",
            "title": "Credit"
          },
          "credit_values": {
            "description": "Source codes meaning credit.",
            "items": {
              "type": "string"
            },
            "title": "Credit Values",
            "type": "array"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Currency-code column associated with the amount.",
            "title": "Currency"
          },
          "currency_scope": {
            "description": "Source dimensions fixing currency when no code is present.",
            "items": {
              "type": "string"
            },
            "title": "Currency Scope",
            "type": "array"
          },
          "debit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The debit column of the pair, where the basis is a pair.",
            "title": "Debit"
          },
          "debit_values": {
            "description": "Source codes meaning debit.",
            "items": {
              "type": "string"
            },
            "title": "Debit Values",
            "type": "array"
          },
          "direction": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Column indicating debit or credit.",
            "title": "Direction"
          },
          "magnitude": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unsigned amount column of a directed basis.",
            "title": "Magnitude"
          },
          "name": {
            "description": "The package's own name for this basis, or 'primary' where it labels none.",
            "title": "Name",
            "type": "string"
          },
          "shape": {
            "description": "The source amount representation.",
            "enum": [
              "signed",
              "debit_credit_pair",
              "magnitude_with_direction"
            ],
            "title": "Shape",
            "type": "string"
          },
          "signed": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The single signed amount column, where the basis has no pair.",
            "title": "Signed"
          },
          "ties_to_trial_balance": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether this basis' control totals match the trial balance's movement. Null means nothing has measured it; it is never inferred from a closing balance.",
            "title": "Ties To Trial Balance"
          }
        },
        "required": [
          "name",
          "shape"
        ],
        "title": "BasisWire",
        "type": "object"
      },
      "Body_create_upload_v1_uploads_post": {
        "properties": {
          "file": {
            "contentMediaType": "application/octet-stream",
            "description": "The document to stage for a granular operation.",
            "title": "File",
            "type": "string"
          }
        },
        "required": [
          "file"
        ],
        "title": "Body_create_upload_v1_uploads_post",
        "type": "object"
      },
      "Body_playground_extract_v1_playground_extract_post": {
        "properties": {
          "cf-turnstile-response": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cf-Turnstile-Response"
          },
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          },
          "parse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional JSON object of parse settings, shaped like the `parse` section of the API request.",
            "title": "Parse"
          },
          "schema": {
            "title": "Schema",
            "type": "string"
          }
        },
        "required": [
          "file",
          "schema"
        ],
        "title": "Body_playground_extract_v1_playground_extract_post",
        "type": "object"
      },
      "Body_playground_ground_v1_playground_ground_post": {
        "properties": {
          "cf-turnstile-response": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cf-Turnstile-Response"
          },
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          },
          "parse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional JSON object of parse settings, shaped like the `parse` section of the API request.",
            "title": "Parse"
          },
          "targets": {
            "title": "Targets",
            "type": "string"
          }
        },
        "required": [
          "file",
          "targets"
        ],
        "title": "Body_playground_ground_v1_playground_ground_post",
        "type": "object"
      },
      "Body_playground_parse_v1_playground_parse_post": {
        "properties": {
          "cf-turnstile-response": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cf-Turnstile-Response"
          },
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          },
          "parse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional JSON object of parse settings, shaped like the `parse` section of the API request.",
            "title": "Parse"
          }
        },
        "required": [
          "file"
        ],
        "title": "Body_playground_parse_v1_playground_parse_post",
        "type": "object"
      },
      "Body_playground_split_v1_playground_split_post": {
        "properties": {
          "cf-turnstile-response": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cf-Turnstile-Response"
          },
          "classes": {
            "title": "Classes",
            "type": "string"
          },
          "file": {
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "type": "string"
          },
          "parse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional JSON object of parse settings, shaped like the `parse` section of the API request.",
            "title": "Parse"
          }
        },
        "required": [
          "file",
          "classes"
        ],
        "title": "Body_playground_split_v1_playground_split_post",
        "type": "object"
      },
      "Body_replace_file_v1_workspaces__workspace_id__files__file_id__put": {
        "properties": {
          "file": {
            "anyOf": [
              {
                "contentMediaType": "application/octet-stream",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File"
          },
          "metadata": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "JSON-encoded ReplaceFileRequest. Required for multipart uploads.",
            "title": "Metadata"
          }
        },
        "title": "Body_replace_file_v1_workspaces__workspace_id__files__file_id__put",
        "type": "object"
      },
      "Body_upload_file_v1_workspaces__workspace_id__files_post": {
        "properties": {
          "file": {
            "anyOf": [
              {
                "contentMediaType": "application/octet-stream",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File"
          },
          "metadata": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "JSON-encoded UploadFileRequest. Required for multipart uploads.",
            "title": "Metadata"
          }
        },
        "title": "Body_upload_file_v1_workspaces__workspace_id__files_post",
        "type": "object"
      },
      "BooleanCell": {
        "additionalProperties": false,
        "properties": {
          "kind": {
            "const": "boolean",
            "default": "boolean",
            "title": "Kind",
            "type": "string"
          },
          "value": {
            "title": "Value",
            "type": "boolean"
          }
        },
        "required": [
          "value"
        ],
        "title": "BooleanCell",
        "type": "object"
      },
      "BoundColumn": {
        "additionalProperties": false,
        "description": "One column the run pinned to a definitional slot.",
        "properties": {
          "column": {
            "title": "Column",
            "type": "string"
          },
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Component"
          },
          "detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the slot additionally states about this column — a clock's true grain, that a basis is the one the trial balance ties to, what a calendar date means.",
            "title": "Detail"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "slot": {
            "description": "The slot this column fills, dotted: 'journal_key', 'clocks.created', 'amount_bases[reporting].debit', 'accounts.fsli'.",
            "title": "Slot",
            "type": "string"
          },
          "table_name": {
            "title": "Table Name",
            "type": "string"
          }
        },
        "required": [
          "slot",
          "path",
          "table_name",
          "column"
        ],
        "title": "BoundColumn",
        "type": "object"
      },
      "BoundPeriod": {
        "additionalProperties": false,
        "description": "One value of the period axis and the role the run gave it, in period order.",
        "properties": {
          "role": {
            "description": "'opening', 'month', 'year_end_adj' or 'total_row'.",
            "title": "Role",
            "type": "string"
          },
          "value": {
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "value",
          "role"
        ],
        "title": "BoundPeriod",
        "type": "object"
      },
      "BoundTable": {
        "additionalProperties": false,
        "description": "One table of the package, and the role the run bound it to.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The tab, when the file contributed more than one table.",
            "title": "Component"
          },
          "path": {
            "description": "The uploaded file, e.g. 'ledger/journal.xlsx'.",
            "title": "Path",
            "type": "string"
          },
          "role": {
            "description": "The slot it fills: 'journal_lines', 'journal_headers', 'trial_balance', ….",
            "title": "Role",
            "type": "string"
          },
          "table_name": {
            "description": "The view name this run's SQL referenced it by.",
            "title": "Table Name",
            "type": "string"
          }
        },
        "required": [
          "role",
          "path",
          "table_name"
        ],
        "title": "BoundTable",
        "type": "object"
      },
      "BoundValueSet": {
        "additionalProperties": false,
        "description": "One column-and-values pin: an encoding candidate, or a layer's membership.\n\nNamed even when its slot carries only one, because the name is what a test\ncites when a slot carries two — which is a state this binding may legitimately\nbe in. Two candidates of ``encodings.manual`` published here means the run\nkept both readings of \"manual\" alive and chose between them per test, which is\nwhat the answer's own working will say.",
        "properties": {
          "column": {
            "title": "Column",
            "type": "string"
          },
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Component"
          },
          "name": {
            "description": "The candidate's name, as a test spec cites it.",
            "title": "Name",
            "type": "string"
          },
          "note": {
            "default": "",
            "description": "Where this reading came from — a policy sheet, a flag column, a profiled domain.",
            "title": "Note",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "slot": {
            "description": "'encodings.posted', 'encodings.manual', 'layers.book', ….",
            "title": "Slot",
            "type": "string"
          },
          "table_name": {
            "title": "Table Name",
            "type": "string"
          },
          "values": {
            "description": "The values of that column which mean this.",
            "items": {
              "type": "string"
            },
            "title": "Values",
            "type": "array"
          }
        },
        "required": [
          "slot",
          "name",
          "path",
          "table_name",
          "column"
        ],
        "title": "BoundValueSet",
        "type": "object"
      },
      "CancelJobRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /jobs/{job_id}/cancel``.\n\n``reason`` is stored in the job's ``error`` payload so an audit trail\nrecords who cancelled and why.  It is surfaced to the caller on the next\npoll rather than lost.",
        "properties": {
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason"
          }
        },
        "title": "CancelJobRequest",
        "type": "object"
      },
      "CatalogColumnDescriptor": {
        "additionalProperties": false,
        "description": "One extracted field the result's rows may carry.",
        "properties": {
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "field": {
            "title": "Field",
            "type": "string"
          },
          "filtered": {
            "default": false,
            "description": "The published query filtered on this column — or ranked by it under a top-N LIMIT, where ranking decides membership (server-extracted from the SQL, never model-authored). These are the values the matches hinge on, and the first cells worth grounding against their source documents.",
            "title": "Filtered",
            "type": "boolean"
          },
          "kind": {
            "enum": [
              "text",
              "date",
              "money",
              "number",
              "boolean"
            ],
            "title": "Kind",
            "type": "string"
          },
          "repeated": {
            "default": false,
            "description": "Several values may exist per row (parties, signatories).",
            "title": "Repeated",
            "type": "boolean"
          },
          "requested": {
            "default": false,
            "description": "The user requested this output field; missing values do not exclude a match.",
            "title": "Requested",
            "type": "boolean"
          }
        },
        "required": [
          "field",
          "kind"
        ],
        "title": "CatalogColumnDescriptor",
        "type": "object"
      },
      "CatalogEmptyTable": {
        "additionalProperties": false,
        "properties": {
          "columns": {
            "description": "The table's column names; the populated tables describe them.",
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "document_type": {
            "description": "The document type the table would hold, e.g. `Invoice`.",
            "title": "Document Type",
            "type": "string"
          },
          "table": {
            "description": "The table's name, as a catalog SELECT spells it.",
            "title": "Table",
            "type": "string"
          }
        },
        "required": [
          "table",
          "document_type",
          "columns"
        ],
        "title": "CatalogEmptyTable",
        "type": "object"
      },
      "CatalogTable": {
        "additionalProperties": false,
        "properties": {
          "columns": {
            "description": "Every column the table has, in order.",
            "items": {
              "$ref": "#/components/schemas/CatalogTableColumn"
            },
            "title": "Columns",
            "type": "array"
          },
          "description": {
            "description": "Which records the table holds.",
            "title": "Description",
            "type": "string"
          },
          "in_scope_components": {
            "description": "Catalog records (document sections, tabs) the caller may see.",
            "title": "In Scope Components",
            "type": "integer"
          },
          "table": {
            "description": "The table's name, as a catalog SELECT spells it.",
            "title": "Table",
            "type": "string"
          }
        },
        "required": [
          "table",
          "description",
          "in_scope_components",
          "columns"
        ],
        "title": "CatalogTable",
        "type": "object"
      },
      "CatalogTableColumn": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "description": "What the column holds, and how to filter on it.",
            "title": "Description",
            "type": "string"
          },
          "kind": {
            "description": "text, date, money, number, boolean, or identity (`record_id`).",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "description": "The column's name, as a catalog SELECT spells it.",
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "kind",
          "description"
        ],
        "title": "CatalogTableColumn",
        "type": "object"
      },
      "CatalogToolRequest": {
        "additionalProperties": false,
        "description": "``catalog``: no ``sql`` describes the catalog's tables; one ``sql`` runs a read-only SELECT over them.",
        "properties": {
          "sql": {
            "anyOf": [
              {
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "One read-only SELECT (or WITH ... SELECT) over the catalog tables; omit to list the tables.",
            "title": "Sql"
          }
        },
        "title": "CatalogToolRequest",
        "type": "object"
      },
      "CatalogToolResponse": {
        "additionalProperties": false,
        "description": "A describe fills ``tables``/``empty_tables``; a query fills ``columns``/``rows``/``row_count``/``truncated``.",
        "properties": {
          "columns": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "With `sql`: the result's column names, in order.",
            "title": "Columns"
          },
          "credits": {
            "default": 0,
            "description": "This inline catalog answer creates no job and bills no credits.",
            "minimum": 0.0,
            "title": "Credits",
            "type": "integer"
          },
          "empty_tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/CatalogEmptyTable"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Document types with no records here: queryable, every query over them is empty.",
            "title": "Empty Tables"
          },
          "row_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "With `sql`: how many rows `rows` holds.",
            "title": "Row Count"
          },
          "rows": {
            "anyOf": [
              {
                "items": {
                  "additionalProperties": {
                    "$ref": "#/components/schemas/JsonValue"
                  },
                  "type": "object"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "With `sql`: the result rows, each keyed by column name.",
            "title": "Rows"
          },
          "tables": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/CatalogTable"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Without `sql`: `catalog_document` and every document-type table with records.",
            "title": "Tables"
          },
          "truncated": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "True when the result had more rows than were returned.",
            "title": "Truncated"
          },
          "waiver": {
            "const": "no_job",
            "default": "no_job",
            "description": "This tool answers inline without creating a billable job.",
            "title": "Waiver",
            "type": "string"
          }
        },
        "title": "CatalogToolResponse",
        "type": "object"
      },
      "CategorizeJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "categorize",
            "default": "categorize",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ndi_service__app__platform_api__results__CategorizeResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "CategorizeJob",
        "type": "object"
      },
      "CategorizeRequestEcho": {
        "additionalProperties": false,
        "description": "A stored ``categorize`` request, read back.",
        "properties": {
          "allow_unknown": {
            "default": true,
            "description": "When true, the model may assign none of the above if nothing fits confidently.",
            "title": "Allow Unknown",
            "type": "boolean"
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "domain_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Registered domain vocabulary to classify against when taxonomy is omitted.",
            "title": "Domain Id"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the Parse that runs before this operation, using the same fields as Parse. Omit to use the default Parse. parse.parse_mode and the top-level parse_mode must agree when both are set, and so must parse.page_ranges and page_ranges. A setting that does not apply is reported in warnings."
          },
          "parse_mode": {
            "default": "low",
            "description": "How much parsing effort to use: Low uses native OCR, Medium routes to the best parser, and High adds page verification and correction.",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Parse Mode",
            "type": "string"
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "request_type": {
            "const": "categorize",
            "default": "categorize",
            "title": "Request Type",
            "type": "string"
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Single document to classify. Exactly one of source or sources must be set.",
            "title": "Source"
          },
          "sources": {
            "anyOf": [
              {
                "items": {
                  "discriminator": {
                    "mapping": {
                      "parse_result": "#/components/schemas/ParseResultSource",
                      "upload": "#/components/schemas/UploadSource",
                      "url": "#/components/schemas/UrlSource",
                      "workspace_file": "#/components/schemas/WorkspaceFileSource"
                    },
                    "propertyName": "type"
                  },
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/UploadSource"
                    },
                    {
                      "$ref": "#/components/schemas/UrlSource"
                    },
                    {
                      "$ref": "#/components/schemas/WorkspaceFileSource"
                    },
                    {
                      "$ref": "#/components/schemas/ParseResultSource"
                    }
                  ]
                },
                "maxItems": 50,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Batch of documents to classify. Exactly one of source or sources must be set.",
            "title": "Sources"
          },
          "taxonomy": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CategorizeTaxonomy"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-provided two-level category tree. Omit to use the domain vocabulary."
          },
          "vocabulary": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy flat category list. Prefer taxonomy or a registered domain_id.",
            "title": "Vocabulary"
          }
        },
        "title": "CategorizeRequestEcho",
        "type": "object"
      },
      "CategorizeTaxonomy": {
        "additionalProperties": false,
        "properties": {
          "allow_freeform": {
            "default": false,
            "title": "Allow Freeform",
            "type": "boolean"
          },
          "categories": {
            "items": {
              "$ref": "#/components/schemas/CategorizeTaxonomyCategory"
            },
            "minItems": 1,
            "title": "Categories",
            "type": "array"
          }
        },
        "required": [
          "categories"
        ],
        "title": "CategorizeTaxonomy",
        "type": "object"
      },
      "CategorizeTaxonomyCategory": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "subcategories": {
            "items": {
              "$ref": "#/components/schemas/CategorizeTaxonomySubcategory"
            },
            "minItems": 1,
            "title": "Subcategories",
            "type": "array"
          }
        },
        "required": [
          "key",
          "subcategories"
        ],
        "title": "CategorizeTaxonomyCategory",
        "type": "object"
      },
      "CategorizeTaxonomySubcategory": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "key": {
            "title": "Key",
            "type": "string"
          }
        },
        "required": [
          "key"
        ],
        "title": "CategorizeTaxonomySubcategory",
        "type": "object"
      },
      "CategoryAssignment": {
        "additionalProperties": false,
        "properties": {
          "alternatives": {
            "items": {
              "$ref": "#/components/schemas/ScoredCategory"
            },
            "title": "Alternatives",
            "type": "array"
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null when nothing cleared the threshold.",
            "title": "Category"
          },
          "confidence": {
            "title": "Confidence",
            "type": "number"
          },
          "evidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Evidence"
              },
              {
                "type": "null"
              }
            ]
          },
          "file_name": {
            "title": "File Name",
            "type": "string"
          },
          "source_index": {
            "description": "Index into the request's sources list.",
            "title": "Source Index",
            "type": "integer"
          }
        },
        "required": [
          "source_index",
          "file_name",
          "confidence"
        ],
        "title": "CategoryAssignment",
        "type": "object"
      },
      "CategoryCount": {
        "additionalProperties": false,
        "description": "Count of files assigned to a single document category.",
        "properties": {
          "count": {
            "description": "Number of files in scope with this category.",
            "title": "Count",
            "type": "integer"
          },
          "name": {
            "description": "Category path as assigned at ingestion, e.g. `contracts/agreement`.",
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "count"
        ],
        "title": "CategoryCount",
        "type": "object"
      },
      "CheckExecutionWire": {
        "additionalProperties": false,
        "description": "One statement's result; completed with no findings is still a measurement.",
        "properties": {
          "check": {
            "description": "Integrity check identifier.",
            "title": "Check",
            "type": "string"
          },
          "finding_count": {
            "default": 0,
            "description": "Findings returned by this statement, including informational totals.",
            "title": "Finding Count",
            "type": "integer"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Missing prerequisite or execution error.",
            "title": "Reason"
          },
          "resource_failure": {
            "anyOf": [
              {
                "enum": [
                  "spill_capacity",
                  "memory"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exhausted engine resource, without source paths or values.",
            "title": "Resource Failure"
          },
          "scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Statement scope or column, when applicable.",
            "title": "Scope"
          },
          "status": {
            "description": "Execution outcome, not a data-quality verdict.",
            "enum": [
              "completed",
              "failed",
              "skipped",
              "not_run_due_to_resource_failure"
            ],
            "title": "Status",
            "type": "string"
          },
          "table": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ledger table the statement concerns.",
            "title": "Table"
          }
        },
        "required": [
          "check",
          "status"
        ],
        "title": "CheckExecutionWire",
        "type": "object"
      },
      "ChoiceAnswer": {
        "additionalProperties": false,
        "properties": {
          "choice": {
            "description": "The most probable option, by its key in the question's criteria.",
            "title": "Choice",
            "type": "string"
          },
          "confidence": {
            "description": "The decision model's average confidence in this answer, from 0 to 1. It tracks the chosen option's probability but is a separate number; do not derive one from the other.",
            "title": "Confidence",
            "type": "number"
          },
          "probabilities": {
            "additionalProperties": {
              "type": "number"
            },
            "description": "Every option's probability, keyed by option name.",
            "title": "Probabilities",
            "type": "object"
          },
          "type": {
            "const": "choice",
            "default": "choice",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "choice",
          "confidence",
          "probabilities"
        ],
        "title": "ChoiceAnswer",
        "type": "object"
      },
      "ChoiceQuestion": {
        "additionalProperties": false,
        "description": "Pick one of named options. Its answer is the chosen option and every option's probability.",
        "properties": {
          "criteria": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "description": "The options, keyed by the name the answer returns, each with an optional description.",
            "maxProperties": 255,
            "minProperties": 1,
            "propertyNames": {
              "minLength": 1
            },
            "title": "Criteria",
            "type": "object"
          },
          "instructions": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question that the options answer.",
            "title": "Instructions"
          },
          "type": {
            "const": "choice",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "type",
          "criteria"
        ],
        "title": "ChoiceQuestion",
        "type": "object"
      },
      "Citation": {
        "additionalProperties": false,
        "description": "Where an extracted value was found, with optional quoted source text.",
        "properties": {
          "location": {
            "description": "Where in the source the value was read.",
            "discriminator": {
              "mapping": {
                "json_pointer": "#/components/schemas/JsonPointer",
                "page_region": "#/components/schemas/PageRegion",
                "row_range": "#/components/schemas/RowRange",
                "sheet_range": "#/components/schemas/SheetRange",
                "table_region": "#/components/schemas/TableRegion",
                "text_span": "#/components/schemas/TextSpan"
              },
              "propertyName": "kind"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/PageRegion"
              },
              {
                "$ref": "#/components/schemas/SheetRange"
              },
              {
                "$ref": "#/components/schemas/TextSpan"
              },
              {
                "$ref": "#/components/schemas/RowRange"
              },
              {
                "$ref": "#/components/schemas/TableRegion"
              },
              {
                "$ref": "#/components/schemas/JsonPointer"
              }
            ],
            "title": "Location"
          },
          "source_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Short quote from the source at that location. Null when citations omit source text.",
            "title": "Source Text"
          },
          "word_anchor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WordAnchor"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unique literal occurrence in the original DOCX/DOCM text, when native provenance is available."
          }
        },
        "required": [
          "location"
        ],
        "title": "Citation",
        "type": "object"
      },
      "Claim": {
        "additionalProperties": false,
        "description": "Legacy input shape for locating text in a document.\n\n``hint`` is an optional free-text description of where in the document\nthe text is expected to appear; it helps the retrieval step focus.",
        "properties": {
          "claim_id": {
            "title": "Claim Id",
            "type": "string"
          },
          "hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Hint"
          },
          "text": {
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "claim_id",
          "text"
        ],
        "title": "Claim",
        "type": "object"
      },
      "ClarificationAnswer": {
        "additionalProperties": false,
        "description": "The user's answer to one clarifying question a run asked instead of answering.",
        "properties": {
          "answer": {
            "anyOf": [
              {
                "maxLength": 4096,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The answer: one of the question's `options`, or your own words. Null skips the question; the agent then uses its best judgment and states the assumption in its answer.",
            "title": "Answer"
          },
          "question": {
            "description": "The question being answered, as the asking result's `clarification_questions[].question` states it.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Question",
            "type": "string"
          }
        },
        "required": [
          "question"
        ],
        "title": "ClarificationAnswer",
        "type": "object"
      },
      "ClarifyingQuestion": {
        "additionalProperties": false,
        "description": "One question a run asked back instead of answering.",
        "properties": {
          "options": {
            "description": "Suggested answers, most likely first. Never exhaustive: the user may always answer in their own words, so no option stands for 'Other'. Empty when the run offered none.",
            "items": {
              "type": "string"
            },
            "title": "Options",
            "type": "array"
          },
          "question": {
            "description": "The question, as the run asked it.",
            "title": "Question",
            "type": "string"
          }
        },
        "required": [
          "question"
        ],
        "title": "ClarifyingQuestion",
        "type": "object"
      },
      "ClassificationGapFillDisclosure": {
        "additionalProperties": false,
        "description": "Pages left unclassified by the model were assigned a fallback label.\n\nThe classification still succeeded. Gap-filled pages should be treated\nas lower-confidence assignments rather than absences. One disclosure is\nemitted per distinct fallback label; ``filled_pages`` in that disclosure\nare exactly the pages that received ``fallback_label``.",
        "properties": {
          "code": {
            "const": "classification_gap_fill",
            "title": "Code",
            "type": "string"
          },
          "fallback_label": {
            "description": "The classification label applied to every page in filled_pages.",
            "title": "Fallback Label",
            "type": "string"
          },
          "filled_pages": {
            "description": "Exact 1-based pages assigned a fallback label because the model left them unclassified.",
            "items": {
              "minimum": 1.0,
              "type": "integer"
            },
            "minItems": 1,
            "title": "Filled Pages",
            "type": "array"
          }
        },
        "required": [
          "code",
          "filled_pages",
          "fallback_label"
        ],
        "title": "ClassificationGapFillDisclosure",
        "type": "object"
      },
      "ClassificationUnreadPagesDisclosure": {
        "additionalProperties": false,
        "description": "Pages never entered any model prompt and are therefore unknown.\n\nThe classification still succeeded. These pages were dropped by the\ndocument-size batch or token cap, so no model produced a label for them.\nThey carry the reserved unknown label regardless of unknown_policy and\nmust not be read as gap-fill (the model never saw them).",
        "properties": {
          "code": {
            "const": "classification_unread_pages",
            "title": "Code",
            "type": "string"
          },
          "unread_pages": {
            "description": "Exact 1-based pages that never entered any model prompt and are returned unknown because no model produced a label for them.",
            "items": {
              "minimum": 1.0,
              "type": "integer"
            },
            "minItems": 1,
            "title": "Unread Pages",
            "type": "array"
          }
        },
        "required": [
          "code",
          "unread_pages"
        ],
        "title": "ClassificationUnreadPagesDisclosure",
        "type": "object"
      },
      "ClassifyClass": {
        "additionalProperties": false,
        "properties": {
          "criteria": {
            "description": "Optional extra rules the model should apply when scoring this class.",
            "items": {
              "type": "string"
            },
            "title": "Criteria",
            "type": "array"
          },
          "description": {
            "default": "",
            "description": "What belongs in this class. Used as model guidance.",
            "title": "Description",
            "type": "string"
          },
          "id": {
            "description": "Stable caller-defined id returned on labels. Not the reserved other group.",
            "title": "Id",
            "type": "string"
          },
          "label": {
            "description": "Human-readable class name shown in results.",
            "title": "Label",
            "type": "string"
          },
          "subclasses": {
            "description": "Optional finer labels nested under this class.",
            "items": {
              "$ref": "#/components/schemas/ClassifySubclass"
            },
            "title": "Subclasses",
            "type": "array"
          }
        },
        "required": [
          "id",
          "label"
        ],
        "title": "ClassifyClass",
        "type": "object"
      },
      "ClassifyContext": {
        "additionalProperties": false,
        "description": "Caller-supplied context about the document being classified.\n\nToday this carries only the audited entity's name. Direction-sensitive\ncategories (``supplier_invoice`` vs ``sales_invoice``, ``customer_purchase_order``\nvs ``purchase_order``, and similar pairs across the taxonomy) read the same\ndocument two different ways depending on which side of it is the audited\nentity, and the model is never told that otherwise. Naming it here lets the\ndecision read the document's own buyer/supplier or issuer/recipient cues\nagainst the right side.",
        "properties": {
          "entity_aliases": {
            "description": "Other names the audited entity is known by in its documents (trading names, former names, abbreviations).",
            "items": {
              "maxLength": 200,
              "type": "string"
            },
            "maxItems": 10,
            "title": "Entity Aliases",
            "type": "array"
          },
          "entity_name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The audited entity's name, exactly as it would appear on its own letterhead or as the counterparty on a document it did not issue. Omit when the caller does not know it or it does not apply; direction-sensitive categories are then decided without the hint, as they always have been.",
            "title": "Entity Name"
          }
        },
        "title": "ClassifyContext",
        "type": "object"
      },
      "ClassifyJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "classify",
            "default": "classify",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ClassifyResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present on succeeded while retained. Also present on a running classify job whose labels were published before the reason finished."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "ClassifyJob",
        "type": "object"
      },
      "ClassifyLabel": {
        "additionalProperties": false,
        "properties": {
          "class_id": {
            "description": "Id of this label. One of the request classes, or the reserved id other when no requested class matched this slice. other can be the top label when the unit is unknown, or a ranked alternative when some pages did not match. Join request classes on this only when the id is in your classes list.",
            "title": "Class Id",
            "type": "string"
          },
          "confidence": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "DREX's probability for this label, averaged over the menu orders, when DREX decided it. A document label shared by several segments is the page-weighted mean of the probability recorded on each segment, when every label in the unit has one. Labels are ordered by page coverage. Confidence is per label, so a lower rank can carry a higher confidence. An abstained unit's top label is that mean. Its runner-up labels carry DREX's probability for that runner-up option. When any other label in the unit lacks a DREX probability, every such label uses the share of the unit (pages or sheets) assigned that class. Runner-up labels on an abstained unit do not use that share.",
            "title": "Confidence"
          },
          "label": {
            "description": "Display name of that class. Copied from the request for a caller-defined class_id; a freeform name when class_id is other.",
            "title": "Label",
            "type": "string"
          },
          "rank": {
            "description": "1-based position in this unit's labels after classes are sorted by score. 1 is the assigned (or top) class; later ranks are alternatives kept by output.max_alternatives.",
            "minimum": 1.0,
            "title": "Rank",
            "type": "integer"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Short model explanation for this label, only when output.include_reason is true. For the top label, why that class was chosen. For a later rank on an abstained unit, why that class was close but not the pick.",
            "title": "Reason"
          },
          "subclass_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Subclass id when the assignment is a nested class. Null for a top-level class.",
            "title": "Subclass Id"
          }
        },
        "required": [
          "class_id",
          "label",
          "rank"
        ],
        "title": "ClassifyLabel",
        "type": "object"
      },
      "ClassifyOutputOptions": {
        "additionalProperties": false,
        "properties": {
          "delivery": {
            "default": "progressive",
            "description": "Progressive publishes labels on the running job before the reason finishes. Complete waits for reasons (or their failure) before any result. Only meaningful when include_reason is true. Does not change the final result.",
            "enum": [
              "progressive",
              "complete"
            ],
            "title": "Delivery",
            "type": "string"
          },
          "include_reason": {
            "default": true,
            "description": "When true, each label may include a short reason string.",
            "title": "Include Reason",
            "type": "boolean"
          },
          "max_alternatives": {
            "default": 3,
            "description": "How many ranked labels to return per unit, including the winner.",
            "maximum": 10.0,
            "minimum": 1.0,
            "title": "Max Alternatives",
            "type": "integer"
          }
        },
        "title": "ClassifyOutputOptions",
        "type": "object"
      },
      "ClassifyPageRange": {
        "additionalProperties": false,
        "properties": {
          "end": {
            "description": "Last page of this unit, 1-based and inclusive.",
            "minimum": 1.0,
            "title": "End",
            "type": "integer"
          },
          "start": {
            "description": "First page of this unit, 1-based and inclusive.",
            "minimum": 1.0,
            "title": "Start",
            "type": "integer"
          }
        },
        "required": [
          "start",
          "end"
        ],
        "title": "ClassifyPageRange",
        "type": "object"
      },
      "ClassifyRequest": {
        "additionalProperties": false,
        "description": "Body for canonical ``POST /v1/classify``.\n\nThe canonical p0 surface classifies one document against caller-provided\nclasses. Internally this still adapts onto the shared categorize workflow.",
        "properties": {
          "classes": {
            "description": "Caller-defined classes to score the document against.",
            "items": {
              "$ref": "#/components/schemas/ClassifyClass"
            },
            "minItems": 1,
            "title": "Classes",
            "type": "array"
          },
          "context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ClassifyContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-supplied context about the document, such as the audited entity's name."
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "granularity": {
            "default": "document",
            "description": "Score the whole document once, or return one unit per selected page.",
            "enum": [
              "document",
              "page"
            ],
            "title": "Granularity",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "output": {
            "$ref": "#/components/schemas/ClassifyOutputOptions",
            "description": "How many alternative labels to keep and whether to include reasons."
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive page ranges to classify. Omit to use the whole document. Not supported for spreadsheets (.xlsx, .xls, .xlsm, .csv, .parquet): the request is refused with 422 invalid_request and detail.reason spreadsheet_source. A workspace file is a spreadsheet when file_type on GET /v1/workspaces/{workspace_id}/files/{file_id} is one of those extensions.",
            "title": "Page Ranges"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the Parse that runs before this operation, using the same fields as Parse. Omit to use the default Parse. parse.parse_mode and the top-level parse_mode must agree when both are set, and so must parse.page_ranges and page_ranges. A setting that does not apply is reported in warnings."
          },
          "parse_mode": {
            "default": "low",
            "description": "How much parsing effort to use: Low uses native OCR, Medium routes to the best parser, and High adds page verification and correction.",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Parse Mode",
            "type": "string"
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "source": {
            "description": "The document to classify. A parse_result reuses the stored text of a succeeded Parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          },
          "unknown_policy": {
            "default": "allow",
            "description": "allow may mark a unit unknown. force_best commits an ambiguous unit to one of your classes instead of abstaining. A blank or unreadable page the model sees is assigned the closest listed class — the closed decode vocabulary has no page-state tokens. A unit that could not be parsed is still returned unknown, and so is an empty spreadsheet tab. Pages never read by any model because of document size are also returned unknown and disclosed as classification_unread_pages.",
            "enum": [
              "allow",
              "force_best"
            ],
            "title": "Unknown Policy",
            "type": "string"
          }
        },
        "required": [
          "source",
          "classes"
        ],
        "title": "ClassifyRequest",
        "type": "object"
      },
      "ClassifyRequestEcho": {
        "additionalProperties": false,
        "description": "A stored ``classify`` request, read back.",
        "properties": {
          "classes": {
            "description": "Caller-defined classes to score the document against.",
            "items": {
              "$ref": "#/components/schemas/ClassifyClass"
            },
            "minItems": 1,
            "title": "Classes",
            "type": "array"
          },
          "context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ClassifyContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-supplied context about the document, such as the audited entity's name."
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "granularity": {
            "default": "document",
            "description": "Score the whole document once, or return one unit per selected page.",
            "enum": [
              "document",
              "page"
            ],
            "title": "Granularity",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "output": {
            "$ref": "#/components/schemas/ClassifyOutputOptions",
            "description": "How many alternative labels to keep and whether to include reasons."
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive page ranges to classify. Omit to use the whole document. Not supported for spreadsheets (.xlsx, .xls, .xlsm, .csv, .parquet): the request is refused with 422 invalid_request and detail.reason spreadsheet_source. A workspace file is a spreadsheet when file_type on GET /v1/workspaces/{workspace_id}/files/{file_id} is one of those extensions.",
            "title": "Page Ranges"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the Parse that runs before this operation, using the same fields as Parse. Omit to use the default Parse. parse.parse_mode and the top-level parse_mode must agree when both are set, and so must parse.page_ranges and page_ranges. A setting that does not apply is reported in warnings."
          },
          "parse_mode": {
            "default": "low",
            "description": "How much parsing effort to use: Low uses native OCR, Medium routes to the best parser, and High adds page verification and correction.",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Parse Mode",
            "type": "string"
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "request_type": {
            "const": "classify",
            "default": "classify",
            "title": "Request Type",
            "type": "string"
          },
          "source": {
            "description": "The document to classify. A parse_result reuses the stored text of a succeeded Parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          },
          "unknown_policy": {
            "default": "allow",
            "description": "allow may mark a unit unknown. force_best commits an ambiguous unit to one of your classes instead of abstaining. A blank or unreadable page the model sees is assigned the closest listed class — the closed decode vocabulary has no page-state tokens. A unit that could not be parsed is still returned unknown, and so is an empty spreadsheet tab. Pages never read by any model because of document size are also returned unknown and disclosed as classification_unread_pages.",
            "enum": [
              "allow",
              "force_best"
            ],
            "title": "Unknown Policy",
            "type": "string"
          }
        },
        "required": [
          "source",
          "classes"
        ],
        "title": "ClassifyRequestEcho",
        "type": "object"
      },
      "ClassifyResult": {
        "additionalProperties": false,
        "properties": {
          "disclosures": {
            "description": "Structured signals about how this result was produced. Empty when all behaviours matched what the caller would assume without them.",
            "items": {
              "discriminator": {
                "mapping": {
                  "classification_gap_fill": "#/components/schemas/ClassificationGapFillDisclosure",
                  "classification_unread_pages": "#/components/schemas/ClassificationUnreadPagesDisclosure",
                  "content_truncated": "#/components/schemas/ContentTruncatedDisclosure",
                  "extraction_null_on_success": "#/components/schemas/ExtractionNullOnSuccessDisclosure",
                  "parse_fidelity": "#/components/schemas/ParseFidelityDisclosure",
                  "parse_vendor_provenance": "#/components/schemas/ParseVendorProvenanceDisclosure",
                  "source_incomplete": "#/components/schemas/SourceIncompleteDisclosure"
                },
                "propertyName": "code"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ClassificationGapFillDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ClassificationUnreadPagesDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ExtractionNullOnSuccessDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ParseVendorProvenanceDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ParseFidelityDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ContentTruncatedDisclosure"
                },
                {
                  "$ref": "#/components/schemas/SourceIncompleteDisclosure"
                }
              ]
            },
            "title": "Disclosures",
            "type": "array"
          },
          "labels_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When NDI published this job's labels, as an ISO 8601 UTC timestamp, on the same clock as started_at and finished_at. Time to labels is labels_at minus created_at. Reason time is finished_at minus labels_at. Those gaps mean the same thing on every lane. Null on a cache replay, and when labels and the reason arrived together.",
            "title": "Labels At"
          },
          "pages_read_fraction": {
            "default": 1.0,
            "description": "Fraction of expected pages that entered at least one model prompt, from 0 to 1. Equals 1.0 when no pages were unread; otherwise 1 minus unread over expected.",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Pages Read Fraction",
            "type": "number"
          },
          "reason_status": {
            "default": "complete",
            "description": "Pending means labels are available while the top-label reason is still running. Complete means the top-label reason finished. Failed means labels stand and the top-label reason did not finish. A runner-up reason that does not finish leaves that label empty and does not by itself fail the job. Reasons that finished are kept. Not_requested means include_reason was false. Always read the job status for cancellation or failure. Default complete so stored results from before this field validate unchanged.",
            "enum": [
              "pending",
              "complete",
              "failed",
              "not_requested"
            ],
            "title": "Reason Status",
            "type": "string"
          },
          "result_type": {
            "const": "classify",
            "default": "classify",
            "title": "Result Type",
            "type": "string"
          },
          "units": {
            "description": "One scored unit per document, or per page when granularity is page.",
            "items": {
              "$ref": "#/components/schemas/ClassifyUnit"
            },
            "title": "Units",
            "type": "array"
          },
          "unknown_units": {
            "default": 0,
            "description": "Count of units where no requested class won (declined).",
            "title": "Unknown Units",
            "type": "integer"
          },
          "warnings": {
            "description": "Parse settings this run accepted but did not apply, each naming the setting and why, for example a page selection on a file with no pages. Left out when empty.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "units"
        ],
        "title": "ClassifyResult",
        "type": "object"
      },
      "ClassifySubclass": {
        "additionalProperties": false,
        "properties": {
          "criteria": {
            "items": {
              "type": "string"
            },
            "title": "Criteria",
            "type": "array"
          },
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          }
        },
        "required": [
          "id",
          "label"
        ],
        "title": "ClassifySubclass",
        "type": "object"
      },
      "ClassifyUnit": {
        "additionalProperties": false,
        "properties": {
          "granularity": {
            "default": "document",
            "description": "Whether this unit scores the whole document or one page range.",
            "enum": [
              "document",
              "page"
            ],
            "title": "Granularity",
            "type": "string"
          },
          "labels": {
            "description": "Ranked class assignments for this unit, best first.",
            "items": {
              "$ref": "#/components/schemas/ClassifyLabel"
            },
            "title": "Labels",
            "type": "array"
          },
          "page_range": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ClassifyPageRange"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pages this unit covers when granularity is page. Null for a document-level unit."
          },
          "unknown": {
            "description": "True when no requested class won this unit — including reserved other and pages never read by any model — regardless of unknown_policy. False when a requested class won, even if some pages were other.",
            "title": "Unknown",
            "type": "boolean"
          }
        },
        "required": [
          "unknown",
          "labels"
        ],
        "title": "ClassifyUnit",
        "type": "object"
      },
      "ColumnCardWire": {
        "additionalProperties": false,
        "description": "One column as the stage reads it.",
        "properties": {
          "blank_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Rows whose text trims to empty, where the deep profiler measured it.",
            "title": "Blank Count"
          },
          "data_type": {
            "description": "The column's SQL type in the ingested table.",
            "title": "Data Type",
            "type": "string"
          },
          "distinct_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Distinct values, where the census knows the figure.",
            "title": "Distinct Count"
          },
          "distinct_exact": {
            "description": "Whether distinct_count was recounted exactly rather than sketched at ingest time.",
            "title": "Distinct Exact",
            "type": "boolean"
          },
          "max_value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Largest value observed, rendered as text.",
            "title": "Max Value"
          },
          "min_value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Smallest value observed, rendered as text.",
            "title": "Min Value"
          },
          "name": {
            "description": "The column name, as the ingested table spells it.",
            "title": "Name",
            "type": "string"
          },
          "null_count": {
            "description": "Rows where this column is null.",
            "title": "Null Count",
            "type": "integer"
          },
          "role": {
            "description": "What this column is once the binding draft settled it — one of the ledger role names (journal_id, account, amount_debit, effective_date, preparer, …) — or, where nothing settled it, the shape class the census could defend (identifier, category, date, amount, free_text, unknown).",
            "title": "Role",
            "type": "string"
          },
          "values": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ValueCountWire"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The column's whole value domain with row counts, or null when the census does not know it entire. Capped, so a wide domain is reported as null rather than truncated silently.",
            "title": "Values"
          }
        },
        "required": [
          "name",
          "data_type",
          "role",
          "null_count",
          "distinct_exact"
        ],
        "title": "ColumnCardWire",
        "type": "object"
      },
      "CommandReceipt": {
        "additionalProperties": false,
        "properties": {
          "command": {
            "description": "The shell command as executed.",
            "title": "Command",
            "type": "string"
          },
          "outputs": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Named scalar outputs parsed from stdout; a scalar output is named value.",
            "title": "Outputs",
            "type": "object"
          },
          "result_id": {
            "description": "Job-scoped identity of a recorded shell execution.",
            "title": "Result Id",
            "type": "string"
          },
          "stdout": {
            "description": "The complete standard output of the successful command.",
            "title": "Stdout",
            "type": "string"
          }
        },
        "required": [
          "result_id",
          "command",
          "stdout",
          "outputs"
        ],
        "title": "CommandReceipt",
        "type": "object"
      },
      "ConfidenceLevel": {
        "description": "How well the retrieved evidence supports the answer, worst-case wins.",
        "enum": [
          "certain",
          "very_high",
          "high",
          "medium",
          "low",
          "speculative"
        ],
        "title": "ConfidenceLevel",
        "type": "string"
      },
      "ContentConditionMatch": {
        "additionalProperties": false,
        "description": "A verified content criterion attached to the matching result row.",
        "properties": {
          "condition": {
            "description": "The content condition evaluated after catalog filtering.",
            "title": "Condition",
            "type": "string"
          },
          "evidences": {
            "description": "Source passages supporting this row's satisfaction of the condition.",
            "items": {
              "$ref": "#/components/schemas/ContentEvidence"
            },
            "minItems": 1,
            "title": "Evidences",
            "type": "array"
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Observed source value supporting the match, when available as a short value.",
            "title": "Value"
          }
        },
        "required": [
          "condition",
          "evidences"
        ],
        "title": "ContentConditionMatch",
        "type": "object"
      },
      "ContentDownload": {
        "additionalProperties": false,
        "description": "Short-lived URL for a native browser download without API-key headers.",
        "properties": {
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Safe export failure explanation, when failed.",
            "title": "Error"
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Expiry of the ready download grant, as Unix epoch seconds.",
            "title": "Expires At"
          },
          "retry_after_seconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Suggested delay before polling a pending export.",
            "title": "Retry After Seconds"
          },
          "status": {
            "default": "ready",
            "description": "Export state; pending requests should be polled again.",
            "enum": [
              "pending",
              "ready",
              "failed"
            ],
            "title": "Status",
            "type": "string"
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Signed download URL when ready. Treat it as a temporary credential.",
            "title": "Url"
          }
        },
        "title": "ContentDownload",
        "type": "object"
      },
      "ContentEvidence": {
        "additionalProperties": false,
        "description": "One passage that satisfied the residual content condition, server-verified.",
        "properties": {
          "a1_range": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The exact native cell or range containing this quotation, within component.",
            "title": "A1 Range"
          },
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Component"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Page"
          },
          "quote": {
            "title": "Quote",
            "type": "string"
          },
          "source_file_id": {
            "format": "uuid",
            "title": "Source File Id",
            "type": "string"
          },
          "source_path": {
            "title": "Source Path",
            "type": "string"
          }
        },
        "required": [
          "source_path",
          "source_file_id",
          "quote"
        ],
        "title": "ContentEvidence",
        "type": "object"
      },
      "ContentTruncatedDisclosure": {
        "additionalProperties": false,
        "description": "A user-visible content field was truncated before being included in the result.\n\nThe result is otherwise complete. ``unit`` states how both size fields\nshould be interpreted.",
        "properties": {
          "code": {
            "const": "content_truncated",
            "title": "Code",
            "type": "string"
          },
          "original_size": {
            "description": "Size of the content before the reduction was applied.",
            "minimum": 1.0,
            "title": "Original Size",
            "type": "integer"
          },
          "retained_size": {
            "description": "Size of the content retained after the reduction was applied.",
            "minimum": 0.0,
            "title": "Retained Size",
            "type": "integer"
          },
          "target": {
            "$ref": "#/components/schemas/TruncationTarget",
            "description": "Processing area whose input or output was reduced before the result was produced."
          },
          "unit": {
            "$ref": "#/components/schemas/TruncationUnit",
            "description": "Unit shared by original_size and retained_size."
          }
        },
        "required": [
          "code",
          "target",
          "unit",
          "original_size",
          "retained_size"
        ],
        "title": "ContentTruncatedDisclosure",
        "type": "object"
      },
      "ContentVerificationSummary": {
        "additionalProperties": false,
        "description": "Coverage of the bounded content check, separate from catalog coverage.",
        "properties": {
          "candidates": {
            "description": "Catalog candidates considered by the cited content check.",
            "minimum": 0.0,
            "title": "Candidates",
            "type": "integer"
          },
          "condition": {
            "description": "The content condition checked on catalog-selected candidates.",
            "title": "Condition",
            "type": "string"
          },
          "unverified_candidates": {
            "description": "Candidates whose condition could neither be established nor ruled out, including bounds or unavailable evidence. These records are excluded from confirmed matches, not treated as non-matches.",
            "minimum": 0.0,
            "title": "Unverified Candidates",
            "type": "integer"
          }
        },
        "required": [
          "condition",
          "candidates",
          "unverified_candidates"
        ],
        "title": "ContentVerificationSummary",
        "type": "object"
      },
      "ConventionsWire": {
        "additionalProperties": false,
        "description": "What this package's numbers mean, in the terms every test is defined in.",
        "properties": {
          "account_column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The visible account column selected for journal lines.",
            "title": "Account Column"
          },
          "account_columns": {
            "description": "The ordered account identity selected for journal lines.",
            "items": {
              "type": "string"
            },
            "title": "Account Columns",
            "type": "array"
          },
          "account_identity_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Aggregate account-identity proof or refusal reason.",
            "title": "Account Identity Reason"
          },
          "account_identity_status": {
            "default": "legacy",
            "description": "Whether complete-population evidence proved the account identity safe.",
            "enum": [
              "legacy",
              "scalar",
              "scoped",
              "blocked",
              "unmeasured"
            ],
            "title": "Account Identity Status",
            "type": "string"
          },
          "account_scope_columns": {
            "description": "Hidden source dimensions used to keep segmented accounts distinct.",
            "items": {
              "type": "string"
            },
            "title": "Account Scope Columns",
            "type": "array"
          },
          "auxiliary_columns": {
            "additionalProperties": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "description": "Non-exclusive SAP meanings and their qualified physical columns.",
            "title": "Auxiliary Columns",
            "type": "object"
          },
          "bases": {
            "description": "Every amount basis the package spells, with its balance measurement.",
            "items": {
              "$ref": "#/components/schemas/BasisWire"
            },
            "title": "Bases",
            "type": "array"
          },
          "date_roles": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Each date role the stage settled mapped to the column that fills it, using the role vocabulary.",
            "title": "Date Roles",
            "type": "object"
          },
          "entity_column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The column carrying the reporting entity, where one is settled.",
            "title": "Entity Column"
          },
          "entity_values": {
            "description": "The entity values present, where the census knows the domain entire.",
            "items": {
              "type": "string"
            },
            "title": "Entity Values",
            "type": "array"
          },
          "header_columns": {
            "description": "Attributes the journal key determines — one value per journal.",
            "items": {
              "type": "string"
            },
            "title": "Header Columns",
            "type": "array"
          },
          "header_table": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The journal-header table, where the package has one.",
            "title": "Header Table"
          },
          "journal_key": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The columns one journal entry is identified by.",
            "title": "Journal Key"
          },
          "journal_key_aliases": {
            "description": "Other scalar columns proven to identify exactly the same groups of ledger rows.",
            "items": {
              "type": "string"
            },
            "title": "Journal Key Aliases",
            "type": "array"
          },
          "layer_column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The book or overlay axis, where exactly one column carries one. Its split stays open.",
            "title": "Layer Column"
          },
          "ledger_tables": {
            "description": "The tables that hold the journal lines under test.",
            "items": {
              "type": "string"
            },
            "title": "Ledger Tables",
            "type": "array"
          },
          "line_columns": {
            "description": "Attributes that vary within a single journal.",
            "items": {
              "type": "string"
            },
            "title": "Line Columns",
            "type": "array"
          },
          "one_sided_entries": {
            "description": "Whether the package holds journals that post to one side only, or whether nothing measured it.",
            "enum": [
              "none",
              "present",
              "unknown"
            ],
            "title": "One Sided Entries",
            "type": "string"
          },
          "period_column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The column carrying the accounting period axis.",
            "title": "Period Column"
          },
          "period_values": {
            "description": "The period values present, where the census knows the domain entire.",
            "items": {
              "type": "string"
            },
            "title": "Period Values",
            "type": "array"
          },
          "role_sources": {
            "additionalProperties": {
              "$ref": "#/components/schemas/RoleSourceWire"
            },
            "description": "Physical owner and evidence per settled role.",
            "title": "Role Sources",
            "type": "object"
          },
          "unavailable_tests": {
            "description": "Tests this package cannot run because a role they need is absent. Stated rather than left silent, since silence about an untested condition reads as a clean result.",
            "items": {
              "type": "string"
            },
            "title": "Unavailable Tests",
            "type": "array"
          }
        },
        "required": [
          "ledger_tables",
          "bases",
          "date_roles",
          "unavailable_tests",
          "header_columns",
          "line_columns",
          "entity_values",
          "period_values",
          "one_sided_entries"
        ],
        "title": "ConventionsWire",
        "type": "object"
      },
      "CostLine": {
        "additionalProperties": false,
        "description": "One independently priced part of a perception job.",
        "properties": {
          "amount_usd": {
            "description": "This line's USD amount: quantity multiplied by unit_price_usd, serialized as a decimal string.",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,9}0*$",
            "title": "Amount Usd",
            "type": "string"
          },
          "execution": {
            "description": "The price tier: normal work or verified, billing-eligible tenant reuse; not provider token caching.",
            "enum": [
              "fresh",
              "reused"
            ],
            "title": "Execution",
            "type": "string"
          },
          "operation": {
            "description": "The work this dollar amount pays for.",
            "enum": [
              "parse",
              "split",
              "classify",
              "extract",
              "ground"
            ],
            "title": "Operation",
            "type": "string"
          },
          "quantity": {
            "description": "The number of page-equivalents or Ground targets priced by this line.",
            "minimum": 0.0,
            "title": "Quantity",
            "type": "integer"
          },
          "reuse_reason": {
            "anyOf": [
              {
                "enum": [
                  "reused_parse",
                  "repeat_of_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the lower reuse rate applies; null on a normal-price line.",
            "title": "Reuse Reason"
          },
          "unit": {
            "description": "The quantity's billing unit: page-equivalent or Ground target.",
            "enum": [
              "page",
              "item"
            ],
            "title": "Unit",
            "type": "string"
          },
          "unit_price_usd": {
            "description": "USD per unit under the job's pinned price sheet, serialized as a decimal string.",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,9}0*$",
            "title": "Unit Price Usd",
            "type": "string"
          }
        },
        "required": [
          "operation",
          "quantity",
          "unit",
          "execution",
          "unit_price_usd",
          "amount_usd"
        ],
        "title": "CostLine",
        "type": "object"
      },
      "Coverage": {
        "additionalProperties": false,
        "description": "What the access gate withheld, in counts and label names only.\n\nNever a name, path, or fragment of withheld content. Naming the labels\nleaks nothing the caller cannot already read from the workspace config, and\nit turns \"some results were withheld\" into an actionable request.",
        "properties": {
          "labels_required": {
            "description": "Which labels would have been needed to see the withheld candidates.",
            "items": {
              "type": "string"
            },
            "title": "Labels Required",
            "type": "array"
          },
          "request_access_hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Request Access Hint"
          },
          "restricted_candidates": {
            "default": 0,
            "title": "Restricted Candidates",
            "type": "integer"
          }
        },
        "title": "Coverage",
        "type": "object"
      },
      "CreateAccessLabelRequest": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "maxLength": 2000,
            "minLength": 1,
            "title": "Description",
            "type": "string"
          },
          "name": {
            "maxLength": 64,
            "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "description"
        ],
        "title": "CreateAccessLabelRequest",
        "type": "object"
      },
      "CreateDomainRequest": {
        "additionalProperties": false,
        "description": "Creates a taxonomy ``draft`` at version 1 in the caller's tenant.",
        "properties": {
          "display_name": {
            "maxLength": 200,
            "minLength": 1,
            "title": "Display Name",
            "type": "string"
          },
          "slug": {
            "maxLength": 64,
            "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
            "title": "Slug",
            "type": "string"
          },
          "taxonomy": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__domains__schemas__Taxonomy"
          }
        },
        "required": [
          "slug",
          "display_name",
          "taxonomy"
        ],
        "title": "CreateDomainRequest",
        "type": "object"
      },
      "CreateExtractionSchemaRequest": {
        "additionalProperties": false,
        "description": "Create version 1 of a new schema family with a server-generated id.",
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 2000,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "maxLength": 128,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "schema": {
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonValue"
            },
            "title": "Schema",
            "type": "object"
          }
        },
        "required": [
          "name",
          "schema"
        ],
        "title": "CreateExtractionSchemaRequest",
        "type": "object"
      },
      "CreateExtractionSchemaVersionRequest": {
        "additionalProperties": false,
        "description": "Append the next immutable version of an existing tenant-owned family.\n\nOmitted ``name`` / ``description`` inherit the previous version's values so\ncallers can ship a schema-only change without restating metadata.",
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 2000,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 128,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "schema": {
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonValue"
            },
            "title": "Schema",
            "type": "object"
          }
        },
        "required": [
          "schema"
        ],
        "title": "CreateExtractionSchemaVersionRequest",
        "type": "object"
      },
      "CreateUploadGrantRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /workspaces/{workspace_id}/upload-grants``.\n\nEvery field narrows what the grant's holder may do; an empty body mints a\ngrant for one upload anywhere in the workspace with the default TTL.",
        "properties": {
          "max_bytes": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-grant byte cap, tighter than the service-wide cap for the pinned path. Omit to freeze the grant at that cap; an unpinned grant freezes at NDI_MAX_UPLOAD_BYTES.",
            "title": "Max Bytes"
          },
          "path": {
            "anyOf": [
              {
                "description": "Pin the upload to exactly this destination path. The platform-reserved '.workspace' subtree is not allowed. Omit to let the holder choose.",
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^[^/]",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Path"
          },
          "total_size_bytes": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exact expected upload size frozen into the grant. Distinct from max_bytes: a short body is rejected even when it fits under the cap.",
            "title": "Total Size Bytes"
          },
          "ttl_seconds": {
            "default": 3600,
            "description": "How long the grant verifies, in seconds.",
            "maximum": 3600.0,
            "minimum": 1.0,
            "title": "Ttl Seconds",
            "type": "integer"
          }
        },
        "title": "CreateUploadGrantRequest",
        "type": "object"
      },
      "CreateUploadSessionRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /workspaces/{workspace_id}/upload-sessions``.\n\nSame destination/conflict/labelling contract as ``UploadFileRequest`` —\nthis is the chunked entry point to the exact same ledger write, for a\nfile large enough (or a link flaky enough) that one unretried multipart\nPOST is the wrong shape. ``total_size_bytes`` is required and checked\nbyte-for-byte at ``complete``: nothing here is trusted on faith.",
        "properties": {
          "graph_inclusion": {
            "default": "auto",
            "description": "Whether this file joins the knowledge-graph corpus. 'auto' follows the workspace's KG exclusion rules; 'include'/'exclude' override them for this file.",
            "enum": [
              "auto",
              "include",
              "exclude"
            ],
            "title": "Graph Inclusion",
            "type": "string"
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Caller-supplied metadata, stored verbatim.",
            "title": "Labels",
            "type": "object"
          },
          "on_conflict": {
            "default": "reject",
            "description": "'reject' raises path_conflict at complete-time when a file already exists at this path. 'new_version' increments the version and stamps replaced_at on the previous one.",
            "enum": [
              "reject",
              "new_version"
            ],
            "title": "On Conflict",
            "type": "string"
          },
          "path": {
            "description": "Destination path inside the workspace. Relative, must not start with '/', and must not use the platform-reserved '.workspace' subtree.",
            "maxLength": 1024,
            "minLength": 1,
            "pattern": "^[^/]",
            "title": "Path",
            "type": "string"
          },
          "source_modified_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Filesystem modification time reported by the uploading client. Informational only: callers control this value, so it is not audit evidence.",
            "title": "Source Modified At"
          },
          "total_size_bytes": {
            "description": "Exact total size of the file, across every part.",
            "exclusiveMinimum": 0.0,
            "title": "Total Size Bytes",
            "type": "integer"
          },
          "ttl_seconds": {
            "default": 5400,
            "description": "How long the session accepts parts before it expires unfinished.",
            "maximum": 5400.0,
            "minimum": 1.0,
            "title": "Ttl Seconds",
            "type": "integer"
          }
        },
        "required": [
          "path",
          "total_size_bytes"
        ],
        "title": "CreateUploadSessionRequest",
        "type": "object"
      },
      "CreateUploadSessionResponse": {
        "additionalProperties": false,
        "description": "A newly created upload session, ready to accept parts.\n\n``session_token`` is sent as ``X-Upload-Token`` on every subsequent\nrequest against this session (parts, status, complete, abort) — the\nupload grant or API key used to create the session is not sent again.",
        "properties": {
          "chunk_size": {
            "description": "Upload every part at exactly this size, except a shorter final part.",
            "title": "Chunk Size",
            "type": "integer"
          },
          "expires_at": {
            "description": "When the session stops accepting parts.",
            "format": "date-time",
            "title": "Expires At",
            "type": "string"
          },
          "session_id": {
            "format": "uuid",
            "title": "Session Id",
            "type": "string"
          },
          "session_token": {
            "description": "Send in the X-Upload-Token header of every subsequent request.",
            "title": "Session Token",
            "type": "string"
          },
          "total_parts": {
            "description": "ceil(total_size_bytes / chunk_size) — the parts complete() expects.",
            "title": "Total Parts",
            "type": "integer"
          }
        },
        "required": [
          "session_id",
          "session_token",
          "chunk_size",
          "total_parts",
          "expires_at"
        ],
        "title": "CreateUploadSessionResponse",
        "type": "object"
      },
      "CreateWorkspaceRequest": {
        "additionalProperties": false,
        "description": "Provision a new workspace.\n\nEvery field has a default so a caller who knows nothing creates a working\nworkspace with just a name. Creating a workspace ingests nothing and costs\nnothing — it is a namespace plus a configuration.",
        "properties": {
          "access": {
            "$ref": "#/components/schemas/AccessConfig",
            "description": "Access-label configuration. ``labels=[]`` (the default) disables filtering entirely."
          },
          "currency": {
            "$ref": "#/components/schemas/CurrencyPolicy",
            "description": "How to read amounts whose currency the documents leave open. Defaults to USD; send default=null to assume nothing."
          },
          "domain_slug": {
            "default": "generic",
            "description": "Domain vocabulary. Resolved to the latest published version unless pinned.",
            "title": "Domain Slug",
            "type": "string"
          },
          "domain_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pin a specific domain version. Omit to take the latest published.",
            "title": "Domain Version"
          },
          "global_context": {
            "default": "",
            "description": "Standing background for every query in this workspace — how its journals are keyed, which entity it covers, what an auditor already knows. A je-testing or search request that omits `context` runs with this text; a request that sends `context` replaces it for that run, and `\"\"` runs with none. Empty means none. Surrounding whitespace is stripped.",
            "maxLength": 20000,
            "title": "Global Context",
            "type": "string"
          },
          "knowledge_graph": {
            "$ref": "#/components/schemas/KnowledgeGraphConfig",
            "description": "Knowledge-graph build policy. Builds are on demand unless this asks for automatic ones, so a workspace only pays for a graph someone wanted."
          },
          "ledger_understanding": {
            "$ref": "#/components/schemas/LedgerUnderstandingConfig",
            "description": "When to understand the workspace's general ledger — table and column roles, the journal key and its balance proof, and the integrity battery. Runs automatically for a workspace that holds a journal-line table, and costs one that does not nothing."
          },
          "name": {
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "CreateWorkspaceRequest",
        "type": "object"
      },
      "CurrencyPolicy": {
        "additionalProperties": false,
        "description": "How this workspace's documents should be read where they leave a currency open.\n\nExtraction never converts an amount and never invents a currency: one whose\ncurrency the source does not state is recorded as ``ambiguous`` with no\nvalue, so it matches no amount filter. New workspaces default to\n``DEFAULT_WORKSPACE_CURRENCY`` (USD), so a corpus that writes every total as a\nbare ``$900.00`` and names a currency nowhere is filterable out of the box.\nSet ``default`` to another ISO code to change the reading, or to ``null`` to\nassume nothing — an amount whose currency the source never states then stays\n``ambiguous`` rather than being read as USD.",
        "properties": {
          "default": {
            "anyOf": [
              {
                "description": "ISO 4217 code, e.g. 'USD'.",
                "pattern": "^[A-Z]{3}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": "USD",
            "description": "Which currency to read when a document marks an amount with a symbol that names several currencies ($ for USD/CAD/AUD/…, ¥ for JPY/CNY, kr for SEK/NOK/…) and states no ISO code anywhere. Defaults to 'USD'; set another ISO code to change it, or null to leave such an amount ambiguous (and so unfilterable). A resolved amount is recorded with 'currency_source: assumed' in the file's metadata so the assumption stays visible. It only ever disambiguates, never invents: an amount written '€900' is still EUR, a '$900' amount in a EUR-default workspace stays ambiguous (a dollar sign is not a way of writing euros), and an amount carrying no currency marker at all is never given one.",
            "title": "Default"
          }
        },
        "title": "CurrencyPolicy",
        "type": "object"
      },
      "DateCell": {
        "additionalProperties": false,
        "properties": {
          "date": {
            "description": "ISO 8601 calendar date.",
            "title": "Date",
            "type": "string"
          },
          "kind": {
            "const": "date",
            "default": "date",
            "title": "Kind",
            "type": "string"
          }
        },
        "required": [
          "date"
        ],
        "title": "DateCell",
        "type": "object"
      },
      "DeepSearchClaimReference": {
        "additionalProperties": false,
        "description": "A claim's address within a published SQL or command execution receipt.",
        "properties": {
          "cited_value": {
            "description": "The exact value checked against the retained result.",
            "title": "Cited Value",
            "type": "string"
          },
          "column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Result column for a cell claim; null otherwise.",
            "title": "Column"
          },
          "kind": {
            "description": "How the result supports the claim.",
            "enum": [
              "result_cell",
              "result_count",
              "result_absence",
              "command_result"
            ],
            "title": "Kind",
            "type": "string"
          },
          "result_id": {
            "description": "The matching result_id in sql_receipts or command_receipts.",
            "title": "Result Id",
            "type": "string"
          },
          "row": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "0-based result row for a cell claim; null otherwise.",
            "title": "Row"
          }
        },
        "required": [
          "kind",
          "result_id",
          "cited_value"
        ],
        "title": "DeepSearchClaimReference",
        "type": "object"
      },
      "DeepSearchCoverage": {
        "additionalProperties": false,
        "description": "How one requested deliverable was answered, partially answered, or refused.",
        "properties": {
          "absence_result_ids": {
            "description": "Zero-row receipts proving those inputs absent.",
            "items": {
              "type": "string"
            },
            "title": "Absence Result Ids",
            "type": "array"
          },
          "basis": {
            "default": "sql",
            "description": "Whether support is retained SQL or document retrieval; document absence is not a SQL-verified proof.",
            "enum": [
              "sql",
              "document",
              "calculation"
            ],
            "title": "Basis",
            "type": "string"
          },
          "claim_ids": {
            "description": "Verified claims satisfying this output.",
            "items": {
              "type": "string"
            },
            "title": "Claim Ids",
            "type": "array"
          },
          "complete_result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JetBreakdown"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server-rendered rows from the retained listing, never copied from model prose."
          },
          "complete_result_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Receipt containing the requested complete listing; page it when its attached breakdown is truncated.",
            "title": "Complete Result Id"
          },
          "deliverable_id": {
            "description": "Unique id for one requested output.",
            "title": "Deliverable Id",
            "type": "string"
          },
          "description": {
            "description": "Requested output this item accounts for.",
            "title": "Description",
            "type": "string"
          },
          "evidence_indices": {
            "description": "Zero-based indices into this result's published evidences supporting a document deliverable.",
            "items": {
              "type": "integer"
            },
            "title": "Evidence Indices",
            "type": "array"
          },
          "missing_inputs": {
            "description": "Inputs preventing a complete answer.",
            "items": {
              "type": "string"
            },
            "title": "Missing Inputs",
            "type": "array"
          },
          "status": {
            "description": "Whether the output was fully answerable.",
            "enum": [
              "answered",
              "partial",
              "unanswerable"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "deliverable_id",
          "description",
          "status"
        ],
        "title": "DeepSearchCoverage",
        "type": "object"
      },
      "DeepSearchJob": {
        "additionalProperties": false,
        "description": "The consolidated deep-search route's response shape.\n\nOne route, one public ``effort`` knob, one implementation: every new run —\nscoped or not — lands the source-level ``deep_search_v2`` result (answer\nplus SQL receipts). ``intelligent_search`` stays in the ``kind`` union only\nso jobs created by the retired classic loop remain readable via\n``GET /jobs``; ``result_type`` inside the result repeats the discriminator,\nso a caller reading only the result payload can still tell them apart.",
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "description": "deep_search_v2, the source-level agent — every new run, scoped or not. intelligent_search appears only on deep-search jobs created before the 2026-09 consolidation retired the classic scoped loop; those stay readable here.",
            "enum": [
              "intelligent_search",
              "deep_search_v2"
            ],
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IntelligentSearchResult"
              },
              {
                "$ref": "#/components/schemas/DeepSearchV2Result"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained.",
            "title": "Result"
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "kind",
          "status",
          "created_at"
        ],
        "title": "DeepSearchJob",
        "type": "object"
      },
      "DeepSearchRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /workspaces/{workspace_id}/deep-search`` — every agentic search.\n\nEvery run uses one configuration (see\n:mod:`~ndi_service.app.platform_api.intelligent_search.effort`), so no body\nfield selects a model, a tool surface, a reasoning budget, or an effort level.\n``effort``, ``use_kg`` and ``include_answer`` stay on the body only because\npublished SDK, CLI and MCP releases still send them (see\n:data:`RetiredEffort`): deprecated, accepted, and ignored. ``tier`` never\nshipped in a published client and stays rejected by the strict base.\n\nScope never changes the configuration (NDI-573): every run — scoped by\n``paths``/``path_prefix`` or not — gets the same source-level configuration.\nThe folder and file selectors resolve to one file set that every tool\nenforces server-side against the stored job.",
        "properties": {
          "allow_clarification": {
            "default": false,
            "description": "Let the agent finish the run with clarifying questions instead of an answer, when the query is genuinely ambiguous and the ambiguity materially changes the answer. The result then carries the questions in `clarification_questions` (and as text in `clarification`), with `answer` and `reasoning` null and `evidences` empty; answer them in the same thread via the result's `session_id`, with `clarification_answers` or a follow-up query. Off, the default, means the agent always answers with its best reading, stated in the answer.",
            "title": "Allow Clarification",
            "type": "boolean"
          },
          "clarification_answers": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ClarificationAnswer"
                },
                "maxItems": 2,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Answers to the clarifying questions this thread's last turn asked (its result's `clarification_questions`): one entry per question, in order. Send them with that turn's `session_id` and its `query`; the agent then answers that query with the answers applied, and sees which answer belongs to which of its questions. Any other follow-up query in the thread works too — this field is the structured way to answer. Cannot be combined with `allow_clarification`: a run answering questions does not ask again.",
            "title": "Clarification Answers"
          },
          "context": {
            "anyOf": [
              {
                "maxLength": 20000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Free-form background for the model — the engagement, the entity, what the caller already knows. It informs the answer; it does not widen or narrow which files the caller may see.",
            "title": "Context"
          },
          "effort": {
            "anyOf": [
              {
                "enum": [
                  "high",
                  "medium",
                  "low"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "deprecated": true,
            "description": "Deprecated and ignored: the service resolves the run's configuration itself. Accepted so clients released before the effort levels were retired keep working; omit it.",
            "title": "Effort"
          },
          "include_answer": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "deprecated": true,
            "description": "Deprecated and ignored: every run answers. Accepted so clients released before it was retired keep working; omit it.",
            "title": "Include Answer"
          },
          "output_schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A JSON Schema (Draft 2020-12, object root, local non-recursive `$ref` only, no `pattern`, `patternProperties` or `unevaluated*`) the answer must follow. When set, the agent writes `answer` as JSON text conforming to it, the run checks that and asks the agent to correct a mismatch, and the result carries the parsed value in `structured_answer`. A field the source does not state comes back null, whatever type the schema gives it. Explanation goes to `reasoning` where the result has one, and evidences are unchanged. If the answer still misses the schema, the run succeeds with `answer` as written and `structured_answer` null. Omit for a prose answer.",
            "title": "Output Schema"
          },
          "path_prefix": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Put every uploaded file under one folder subtree, workspace-relative, in the run's scope; `paths`, where the body takes it, adds more files. Omit both for the whole workspace.",
            "title": "Path Prefix"
          },
          "paths": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 1024,
                  "minLength": 1,
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Scope the run to exactly these uploaded files. Every retrieval tool the agent runs — search, listings, reads, table queries, the shell — sees only these files and the content ingested from them; everything else is invisible to the run. Each entry names an uploaded source file (never a folder — scope folders with path_prefix; the two add up, so the run covers the folder's files plus these). No limit on how many. Unknown or inaccessible paths are refused up front.",
            "title": "Paths"
          },
          "query": {
            "description": "What to answer, in the caller's own words. Stripped before its length is checked; a blank query is refused rather than run.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Continue a prior deep-search conversation: the id echoed on an earlier result's `session_id`. With the same folder/file scope and access grants, the agent resumes that thread's context. A changed scope or grants starts a fresh conversation and returns a new `session_id`; older threads without a scope snapshot also restart. Omit to start a new thread. Only the API key that started the thread may continue it; a thread whose turn is still running returns 409 session_busy.",
            "title": "Session Id"
          },
          "surface": {
            "default": "deep_search",
            "description": "Which console history this run belongs to. It does not pick the agent, the chassis, or the engine: an omitted value is `deep_search` (the public API and the Deep Search page). The NDI console sends `qa` or `workbook` so Activity and thread lists can split those skins. A follow-up (`session_id`) inherits the thread head's surface; a conflicting value on the follow-up body is ignored.",
            "enum": [
              "deep_search",
              "qa",
              "workbook"
            ],
            "title": "Surface",
            "type": "string"
          },
          "use_kg": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "deprecated": true,
            "description": "Deprecated and ignored: the service decides whether the knowledge graph is consulted. Accepted so clients released before it was retired keep working; omit it.",
            "title": "Use Kg"
          }
        },
        "required": [
          "query"
        ],
        "title": "DeepSearchRequest",
        "type": "object"
      },
      "DeepSearchV2Result": {
        "additionalProperties": false,
        "description": "The result of one source-level deep-search run (``JobKind.DEEP_SEARCH_V2``).\n\nField-for-field the JET shape — answer, reasoning, evidences, the run's\n``sql_receipts``, the tool-call trace, session handle, usage, exhaustion —\nunder its own discriminator: the two kinds share one agent chassis and one\nfold, and a second field list here would only be a place for them to drift.\nOn this surface a receipt's ``rows`` are the statement's bounded preview;\nthe full result is retained server-side and re-queryable through the\n``res_…`` handle appearing in any statement that pages it.",
        "properties": {
          "agent_usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JetAgentUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "Root-agent model requests split into execution, compaction, and recovery finalization. Null on the fixed pipeline and on results stored before this telemetry existed; use `usage` for all nested LLM cost."
          },
          "answer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The direct, grounded answer to the request. Null only on a run that exhausted its budget before authoring one, or that asked `clarification_questions` instead.",
            "title": "Answer"
          },
          "binding": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LedgerBindingWire"
              },
              {
                "type": "null"
              }
            ],
            "description": "The definitional layer the run committed and computed under — which column is the period, which values mean posted, which clock a timing test was verbed on. Null on a run that answered without binding a ledger, which is only possible before any statement ran."
          },
          "cache": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AnswerCacheInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when this answer was re-served from the workspace's answer cache instead of derived by this run, with the provenance of the run that did derive it. Null on every run that computed its own answer."
          },
          "claims": {
            "description": "Calculated answer values, each bound to the execution that produced it.",
            "items": {
              "$ref": "#/components/schemas/DeepSearchVerifiedClaim"
            },
            "title": "Claims",
            "type": "array"
          },
          "clarification": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The run's clarifying questions as plain text, instead of an answer. Only ever set when the request carried `allow_clarification` and the run needed the user's input to go on; `answer` is null and `evidences` empty alongside it. The same questions, structured, are in `clarification_questions`.",
            "title": "Clarification"
          },
          "clarification_questions": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ClarifyingQuestion"
                },
                "maxItems": 2,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The questions behind `clarification`, at most 2, each with up to 4 suggested answers. Answer them with a follow-up on `session_id` that repeats the query and carries `clarification_answers` (one entry per question, a null answer skips it), or with any follow-up query in your own words. Null on every run that answered.",
            "title": "Clarification Questions"
          },
          "command_receipts": {
            "description": "Successful shell calculations cited by this answer.",
            "items": {
              "$ref": "#/components/schemas/CommandReceipt"
            },
            "title": "Command Receipts",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The agent's self-graded confidence in the answer — how well the evidence and executed statements support it, on the shared six-level scale (certain / very_high / high / medium / low / speculative). Deep search publishes an answer that cites no evidence, claim or receipt at medium at most, and JE testing publishes a run with any `incomplete` criterion at medium at most. Null on exhausted runs and on results stored before the field existed."
          },
          "coverage": {
            "description": "Complete result tables the answer attached, each with server-rendered rows.",
            "items": {
              "$ref": "#/components/schemas/DeepSearchCoverage"
            },
            "title": "Coverage",
            "type": "array"
          },
          "criteria": {
            "description": "Every requested test and its final disposition, including tests that never reached binding, measurement, or a published figure. Empty only on results stored before this checklist existed.",
            "items": {
              "$ref": "#/components/schemas/JetCriterionOutcome"
            },
            "title": "Criteria",
            "type": "array"
          },
          "degraded": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this result is degraded, when it is. The run broke before it could finalize an answer but had already computed real working, so what is published is that working — `sql_receipts` and `binding` — with `figures` empty and `answer` saying so. Null on every run that finished normally, exhausted ones included.",
            "title": "Degraded"
          },
          "discrepancies": {
            "description": "Where the data contradicted the request's premise or a figure it stated. Empty when nothing did — the run is asked for this explicitly, so an empty list is an answer rather than an omission.",
            "items": {
              "type": "string"
            },
            "title": "Discrepancies",
            "type": "array"
          },
          "evidences": {
            "description": "The material the answer cites, each resolved to the caller's own uploaded file.",
            "items": {
              "$ref": "#/components/schemas/SearchEvidence"
            },
            "title": "Evidences",
            "type": "array"
          },
          "execution_status": {
            "anyOf": [
              {
                "enum": [
                  "performed",
                  "partially_performed",
                  "not_performed"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the run tested what it was asked to test: ``performed`` when every figure was computed, ``partially_performed`` when some criteria could not be, ``not_performed`` when none could. Read it alongside `quality`, which grades how well a performed test went. JE-testing always sets this on a finished run; other JetResult subclasses (deep search) leave it null, as do results stored before the field existed.",
            "title": "Execution Status"
          },
          "exhausted": {
            "default": false,
            "description": "Step budget hit before the run was satisfied. A successful response, not a failure.",
            "title": "Exhausted",
            "type": "boolean"
          },
          "figures": {
            "description": "One entry per criterion tested, each linked to the receipts its figures are readable out of. Empty on a run that answered without testing anything, or that exhausted its budget first.",
            "items": {
              "$ref": "#/components/schemas/JetFigure"
            },
            "title": "Figures",
            "type": "array"
          },
          "grounding_job_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ground jobs planned for this search's evidences. Empty when postprocessing is disabled for this caller by deployment policy, explicitly disabled for the run, or no evidence is groundable. Absent on older results. When empty or absent, callers may POST /v1/ground explicitly to locate quotes.",
            "title": "Grounding Job Ids"
          },
          "population_statement": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The population every figure was computed over — file, period, layer, status, basis, grain — in the run's own words. Null only on a run that never authored an answer.",
            "title": "Population Statement"
          },
          "quality": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JetQuality"
              },
              {
                "type": "null"
              }
            ],
            "description": "Structured execution quality: clean vs recovered-with-warnings vs degraded, plus the fail-open checks, tool-failure counts, and missing audit artifacts that produced that status. JE-testing always sets this on a finished run. Other JetResult subclasses (deep search) leave it null. Null also on results stored before the field existed."
          },
          "reasoning": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How the receipted statements chain together into the answer.",
            "title": "Reasoning"
          },
          "result_type": {
            "const": "deep_search_v2",
            "default": "deep_search_v2",
            "title": "Result Type",
            "type": "string"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The conversation this run belongs to. Send it back as the request's `session_id` to ask a follow-up in the same thread.",
            "title": "Session Id"
          },
          "spec_digest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A short fingerprint of what this run committed to TEST — the rows, grain, clock, encoding, thresholds and time window each criterion was pinned to — with the free-text justifications beside those choices excluded. Two runs of the same question carry the same value when they tested the same thing, so an unstable answer can be told apart from an answer to a quietly different question without re-reading either run. Null on a run that committed no test spec, and on other JetResult subclasses.",
            "title": "Spec Digest"
          },
          "sql_receipts": {
            "description": "Every statement the run executed, in execution order — the answer's working.",
            "items": {
              "$ref": "#/components/schemas/SqlReceipt"
            },
            "title": "Sql Receipts",
            "type": "array"
          },
          "steps_used": {
            "default": 0,
            "description": "Legacy procedure-step count retained for compatibility. It is engine-specific and is not a model-request count; agent runs expose completed root-model requests in `agent_usage`. Read it with `exhausted`, which says whether the configured request budget ran out before the run was satisfied.",
            "title": "Steps Used",
            "type": "integer"
          },
          "structured_answer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JsonValue"
              },
              {
                "type": "null"
              }
            ],
            "description": "`answer` parsed as JSON, set only when the request carried `output_schema` and the answer validates against it; a field the source does not state is null whatever type the schema gives it. Null on every run without a schema, and on a run whose answer still missed the schema after its corrections, where `answer` holds the text as written."
          },
          "tool_calls": {
            "description": "One entry per tool the run invoked, in execution order — the tool's name, a digest of its arguments, how many results came back, and how long it took. The run's shape, not its content.",
            "items": {
              "$ref": "#/components/schemas/ToolCallTrace"
            },
            "title": "Tool Calls",
            "type": "array"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SearchLlmUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What this run spent on LLM calls. Present only when the request asked for it; null means nothing was measured, not that nothing was spent."
          }
        },
        "title": "DeepSearchV2Result",
        "type": "object"
      },
      "DeepSearchVerifiedClaim": {
        "additionalProperties": false,
        "description": "One calculated answer value, bound to the execution that produced it.",
        "properties": {
          "answer_excerpt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exact displayed answer value selected for its calculation citation.",
            "title": "Answer Excerpt"
          },
          "answer_occurrence": {
            "default": 0,
            "description": "Zero-based occurrence of answer_excerpt in the answer.",
            "minimum": 0.0,
            "title": "Answer Occurrence",
            "type": "integer"
          },
          "claim": {
            "description": "The method or formula behind the calculated value, as the agent wrote it.",
            "title": "Claim",
            "type": "string"
          },
          "claim_id": {
            "description": "Unique id of this calculation within the result.",
            "title": "Claim Id",
            "type": "string"
          },
          "evidence_indices": {
            "description": "Source evidence indices supporting the calculation inputs.",
            "items": {
              "type": "integer"
            },
            "title": "Evidence Indices",
            "type": "array"
          },
          "reference": {
            "$ref": "#/components/schemas/DeepSearchClaimReference",
            "description": "Exact address of the supporting result value."
          }
        },
        "required": [
          "claim_id",
          "claim",
          "reference"
        ],
        "title": "DeepSearchVerifiedClaim",
        "type": "object"
      },
      "DeleteFileJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "file_delete",
            "default": "file_delete",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DeleteFileResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "DeleteFileJob",
        "type": "object"
      },
      "DeleteFileResult": {
        "additionalProperties": false,
        "description": "Counts exist so the cascade is auditable rather than assumed.",
        "properties": {
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "index_documents_deleted": {
            "default": 0,
            "title": "Index Documents Deleted",
            "type": "integer"
          },
          "jobs_cancelled": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Jobs Cancelled",
            "type": "array"
          },
          "kg_edges_deleted": {
            "default": 0,
            "title": "Kg Edges Deleted",
            "type": "integer"
          },
          "kg_nodes_deleted": {
            "default": 0,
            "title": "Kg Nodes Deleted",
            "type": "integer"
          },
          "outputs_deleted": {
            "default": 0,
            "title": "Outputs Deleted",
            "type": "integer"
          },
          "result_type": {
            "const": "file_delete",
            "default": "file_delete",
            "title": "Result Type",
            "type": "string"
          },
          "verified": {
            "description": "False is a failed cascade and must alert.",
            "title": "Verified",
            "type": "boolean"
          }
        },
        "required": [
          "file_id",
          "verified"
        ],
        "title": "DeleteFileResult",
        "type": "object"
      },
      "DeleteFilesResult": {
        "additionalProperties": false,
        "description": "A batch deletion's per-file outcomes plus the cascade's own counts.\n\nThe counts are summed over the files that were actually deleted, and exist\nfor the same reason ``DeleteFileResult``'s do: a caller that asked for\ndeletion can verify it happened rather than assume it. ``verified`` is the\nconjunction over the batch, and ``unverified_file_ids`` names the files\nbehind a false one — an aggregate flag alone would say a cascade failed\nwithout saying for what.",
        "properties": {
          "catalog_rows_deleted": {
            "default": 0,
            "description": "Catalog records and source handles removed across the batch.",
            "title": "Catalog Rows Deleted",
            "type": "integer"
          },
          "deleted": {
            "description": "How many of them were soft-deleted and cascaded.",
            "title": "Deleted",
            "type": "integer"
          },
          "index_documents_deleted": {
            "default": 0,
            "description": "Search-index documents removed across the batch.",
            "title": "Index Documents Deleted",
            "type": "integer"
          },
          "jobs_cancelled": {
            "description": "In-flight jobs that named a deleted file and were cancelled by the cascade.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Jobs Cancelled",
            "type": "array"
          },
          "objects_deleted": {
            "default": 0,
            "description": "Stored objects removed from the deleted files' sibling folders.",
            "title": "Objects Deleted",
            "type": "integer"
          },
          "outcomes": {
            "description": "One entry per requested file, in the order requested.",
            "items": {
              "$ref": "#/components/schemas/FileDeletionOutcome"
            },
            "title": "Outcomes",
            "type": "array"
          },
          "outputs_deleted": {
            "default": 0,
            "description": "Live derived outputs retired across the batch.",
            "title": "Outputs Deleted",
            "type": "integer"
          },
          "requested": {
            "description": "How many file ids the batch named, after duplicates were dropped.",
            "title": "Requested",
            "type": "integer"
          },
          "result_type": {
            "const": "files_delete",
            "default": "files_delete",
            "title": "Result Type",
            "type": "string"
          },
          "unverified_file_ids": {
            "description": "The deleted files whose re-check still found content in some representation.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Unverified File Ids",
            "type": "array"
          },
          "verified": {
            "description": "False is a failed cascade and must alert.",
            "title": "Verified",
            "type": "boolean"
          }
        },
        "required": [
          "requested",
          "deleted",
          "outcomes",
          "verified"
        ],
        "title": "DeleteFilesResult",
        "type": "object"
      },
      "DeleteWorkspaceRequest": {
        "additionalProperties": false,
        "description": "Confirmation payload for an irreversible workspace deletion.",
        "properties": {
          "confirm_name": {
            "description": "Must equal the workspace's name exactly.",
            "title": "Confirm Name",
            "type": "string"
          }
        },
        "required": [
          "confirm_name"
        ],
        "title": "DeleteWorkspaceRequest",
        "type": "object"
      },
      "DerivationStep": {
        "additionalProperties": false,
        "description": "One SQL step in a table-QA derivation DAG.",
        "properties": {
          "kind": {
            "enum": [
              "extraction",
              "transformation"
            ],
            "title": "Kind",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "preview_rows": {
            "items": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "title": "Preview Rows",
            "type": "array"
          },
          "reads": {
            "description": "result_ids this step depends on.",
            "items": {
              "type": "string"
            },
            "title": "Reads",
            "type": "array"
          },
          "result_id": {
            "title": "Result Id",
            "type": "string"
          },
          "sql": {
            "title": "Sql",
            "type": "string"
          }
        },
        "required": [
          "result_id",
          "sql",
          "kind",
          "label"
        ],
        "title": "DerivationStep",
        "type": "object"
      },
      "DerivationTrace": {
        "additionalProperties": false,
        "description": "The answer's computation DAG when evidence is derived rather than extracted.",
        "properties": {
          "steps": {
            "items": {
              "$ref": "#/components/schemas/DerivationStep"
            },
            "title": "Steps",
            "type": "array"
          }
        },
        "title": "DerivationTrace",
        "type": "object"
      },
      "DerivedTableWire": {
        "additionalProperties": false,
        "description": "One Parquet table the parsing pass published beside the report.",
        "properties": {
          "name": {
            "description": "The name the table is joined under in generated SQL.",
            "title": "Name",
            "type": "string"
          },
          "row_count": {
            "description": "Rows in the published file.",
            "title": "Row Count",
            "type": "integer"
          },
          "sha256": {
            "description": "Digest of the published bytes, so a reader can tell two generations apart.",
            "title": "Sha256",
            "type": "string"
          }
        },
        "required": [
          "name",
          "row_count",
          "sha256"
        ],
        "title": "DerivedTableWire",
        "type": "object"
      },
      "DeviceTokenRequest": {
        "description": "``POST /v1/cli/device/token``.",
        "properties": {
          "device_code": {
            "maxLength": 128,
            "minLength": 8,
            "title": "Device Code",
            "type": "string"
          }
        },
        "required": [
          "device_code"
        ],
        "title": "DeviceTokenRequest",
        "type": "object"
      },
      "Domain": {
        "additionalProperties": false,
        "description": "A domain with its effective taxonomy already resolved.\n\nA caller reading a domain wants the taxonomy that will actually be applied,\nnot a delta they have to merge themselves.",
        "properties": {
          "class_count": {
            "title": "Class Count",
            "type": "integer"
          },
          "display_name": {
            "title": "Display Name",
            "type": "string"
          },
          "domain_id": {
            "format": "uuid",
            "title": "Domain Id",
            "type": "string"
          },
          "owner": {
            "enum": [
              "platform",
              "tenant"
            ],
            "title": "Owner",
            "type": "string"
          },
          "parent_slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Inheritance lineage for platform domains that extend a base vocabulary.",
            "title": "Parent Slug"
          },
          "published_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published At"
          },
          "selectable": {
            "description": "True once published; a workspace may only pin a published version.",
            "title": "Selectable",
            "type": "boolean"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          },
          "status": {
            "enum": [
              "draft",
              "published"
            ],
            "title": "Status",
            "type": "string"
          },
          "taxonomy": {
            "$ref": "#/components/schemas/Taxonomy-Output"
          },
          "version": {
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "domain_id",
          "slug",
          "display_name",
          "owner",
          "version",
          "status",
          "class_count",
          "selectable",
          "taxonomy"
        ],
        "title": "Domain",
        "type": "object"
      },
      "DomainResponse": {
        "additionalProperties": false,
        "properties": {
          "domain": {
            "$ref": "#/components/schemas/Domain"
          },
          "validation": {
            "$ref": "#/components/schemas/DomainValidation"
          }
        },
        "required": [
          "domain",
          "validation"
        ],
        "title": "DomainResponse",
        "type": "object"
      },
      "DomainSummary": {
        "additionalProperties": false,
        "description": "A domain without its vocabularies, for listings.",
        "properties": {
          "class_count": {
            "title": "Class Count",
            "type": "integer"
          },
          "display_name": {
            "title": "Display Name",
            "type": "string"
          },
          "domain_id": {
            "format": "uuid",
            "title": "Domain Id",
            "type": "string"
          },
          "owner": {
            "enum": [
              "platform",
              "tenant"
            ],
            "title": "Owner",
            "type": "string"
          },
          "parent_slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Inheritance lineage for platform domains that extend a base vocabulary.",
            "title": "Parent Slug"
          },
          "selectable": {
            "description": "True once published; a workspace may only pin a published version.",
            "title": "Selectable",
            "type": "boolean"
          },
          "slug": {
            "title": "Slug",
            "type": "string"
          },
          "status": {
            "enum": [
              "draft",
              "published"
            ],
            "title": "Status",
            "type": "string"
          },
          "version": {
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "domain_id",
          "slug",
          "display_name",
          "owner",
          "version",
          "status",
          "class_count",
          "selectable"
        ],
        "title": "DomainSummary",
        "type": "object"
      },
      "DomainValidation": {
        "additionalProperties": false,
        "description": "Returned on every domain write, so a caller never has to guess whether a publish will succeed.",
        "properties": {
          "effective_class_count": {
            "title": "Effective Class Count",
            "type": "integer"
          },
          "errors": {
            "items": {
              "$ref": "#/components/schemas/DomainValidationError"
            },
            "title": "Errors",
            "type": "array"
          },
          "valid": {
            "title": "Valid",
            "type": "boolean"
          }
        },
        "required": [
          "valid",
          "effective_class_count"
        ],
        "title": "DomainValidation",
        "type": "object"
      },
      "DomainValidationError": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "title": "Code",
            "type": "string"
          },
          "message": {
            "title": "Message",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "code",
          "path",
          "message"
        ],
        "title": "DomainValidationError",
        "type": "object"
      },
      "Error": {
        "description": "The error object, per spec 12 §1.8.",
        "properties": {
          "code": {
            "$ref": "#/components/schemas/ErrorCode"
          },
          "detail": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Structured payload, when the code carries one.",
            "title": "Detail"
          },
          "message": {
            "description": "Human- and model-readable; says what to do differently.",
            "title": "Message",
            "type": "string"
          },
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-request correlation id; matches the ``X-Request-Id`` header. Null only when the error was minted outside any HTTP request, e.g. by a worker.",
            "title": "Request Id"
          },
          "retryable": {
            "description": "Whether retrying the identical request could succeed.",
            "title": "Retryable",
            "type": "boolean"
          }
        },
        "required": [
          "code",
          "message",
          "retryable"
        ],
        "title": "Error",
        "type": "object"
      },
      "ErrorCode": {
        "description": "Every error the ``/v1`` surface can return.\n\nClients must treat this as an **open** enum: a new member is an additive\nchange (spec 12 §9), and a client that crashes on an unknown code makes\nevery future error a breaking change.",
        "enum": [
          "storage_connection_not_found",
          "storage_connection_in_use",
          "storage_limit_exceeded",
          "storage_conflict",
          "storage_auth_required",
          "storage_unavailable",
          "scan_required",
          "scan_rejected",
          "scan_unavailable",
          "invalid_request",
          "unsupported_file_type",
          "file_too_large",
          "invalid_schema",
          "invalid_sql",
          "invalid_path_prefix",
          "command_not_permitted",
          "batch_too_large",
          "domain_validation_failed",
          "default_label_required",
          "wait_required_for_zero_retention",
          "ledger_decision_invalid",
          "tenant_required",
          "partner_required",
          "workspace_not_found",
          "file_not_found",
          "job_not_found",
          "upload_not_found",
          "node_not_found",
          "schema_not_found",
          "domain_not_found",
          "session_not_found",
          "access_label_not_found",
          "ledger_understanding_not_found",
          "ledger_table_not_found",
          "tenant_not_found",
          "path_conflict",
          "schema_version_conflict",
          "access_label_name_taken",
          "workspace_name_taken",
          "access_label_in_use",
          "upload_expired",
          "file_not_ingested",
          "workspace_deleting",
          "workspace_not_deletable",
          "ingestion_in_progress",
          "job_not_cancellable",
          "confirmation_required",
          "domain_not_published",
          "domain_in_use",
          "reserved_domain_slug",
          "kg_not_built",
          "kg_build_in_progress",
          "ledger_understanding_in_progress",
          "ledger_understanding_version_outdated",
          "session_busy",
          "tenant_limit_reached",
          "range_not_satisfiable",
          "result_expired",
          "access_denied",
          "tenant_disabled",
          "access_backstop_violation",
          "access_mode_not_implemented",
          "rate_limited",
          "concurrency_limit_reached",
          "quota_exceeded",
          "corrupt_file",
          "zero_byte_file",
          "encrypted_file",
          "csv_dialect_ambiguous",
          "csv_parse_failed",
          "parse_failed",
          "ocr_failed",
          "conversion_failed",
          "sheetless_workbook",
          "unplayable_media",
          "unclassified_pages",
          "job_cancelled",
          "job_timeout",
          "upstream_unavailable",
          "internal_error",
          "unauthorized",
          "not_implemented"
        ],
        "title": "ErrorCode",
        "type": "string"
      },
      "ErrorDetail": {
        "additionalProperties": false,
        "description": "Inner error envelope used by :class:`ErrorResponse`.\n\n``request_id`` is populated on every response served inside a request;\ncallers can quote it back to support so we can correlate against logs\nwithout having to share the underlying Postgres row UUID.",
        "properties": {
          "code": {
            "description": "Stable, machine-readable error code (e.g. ``invalid_payload``).",
            "title": "Code",
            "type": "string"
          },
          "message": {
            "description": "Human-readable detail about the error.",
            "title": "Message",
            "type": "string"
          },
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-request correlation id; matches the ``X-Request-Id`` header. Null only when the error was minted outside any HTTP request, e.g. by a worker.",
            "title": "Request Id"
          }
        },
        "required": [
          "code",
          "message"
        ],
        "title": "ErrorDetail",
        "type": "object"
      },
      "ErrorEnvelope": {
        "description": "Every non-2xx body on ``/v1``.",
        "example": {
          "error": {
            "code": "invalid_request",
            "detail": null,
            "message": "Request body has extra fields that this operation does not accept.",
            "request_id": "req-01j9k2n3p4q5r6s7t8v9",
            "retryable": false
          }
        },
        "properties": {
          "error": {
            "$ref": "#/components/schemas/Error"
          }
        },
        "required": [
          "error"
        ],
        "title": "ErrorEnvelope",
        "type": "object"
      },
      "ErrorResponse": {
        "additionalProperties": false,
        "description": "Top-level error body returned by every non-2xx response.\n\nThe OpenAPI schema declares this shape so client SDKs can branch on\n``response.error.code`` deterministically rather than parsing free-form\n``detail`` strings.",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        },
        "required": [
          "error"
        ],
        "title": "ErrorResponse",
        "type": "object"
      },
      "Evidence": {
        "additionalProperties": false,
        "description": "The citation primitive.\n\nEvery result that asserts something about a document or the corpus carries\nit. A synthesised sentence with no evidence behind it is a bug, not a\ndegraded mode.\n\n``path`` is always the uploaded **source** path — that is what every external\naudience (``/v1`` bodies, the console, the search-agent result) is shown. The\ntwo ``exclude=True`` fields below are the host's internal twin of it, for the\naudience that must not see source paths at all (the agent's tools address\ningestion derivatives); they are never serialized, so the ``/v1`` wire shape\nis exactly what it was before they existed.\n\n``component`` closes the loop from a hit back to the file tools: it is the\npublic component name of the hit — exactly the vocabulary ``file-metadata``\nlists and ``qa-file`` / ``read-file`` accept as ``component=`` (the tab name\nfor a spreadsheet, the section/subcategory for a split document). ``None``\nmeans a single-component file or that attribution was unavailable.\n\n``sql_table`` takes the next step for a component that is a table: the name\n``run-sql`` queries it under — a spreadsheet tab's table, or the table every\nrow a document prints in its long tables lands in. Search sets it so a hit\ncan go straight to SQL; other producers leave it ``None``.\n\n``locator`` is present only when the producer actually located the snippet.\n``None`` is not a degraded mode: an engine that answered from a whole\ncomponent (the QA agent's quotes, the DuckDB agent's SQL receipts) asserts\nthe file and ``component``, nothing finer. Pinning such a snippet to a\nregion — a page bbox, a sheet cell range — is a separate ``ground`` call on\n``path`` with ``snippet`` as the target text (and ``component`` as the\n``sheet`` hint when the file is a spreadsheet).",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Public component of the hit, in the vocabulary file-metadata lists and qa-file/read-file accept as component= (tab name for spreadsheets, section for split documents); None for a single-component file or when attribution is unavailable.",
            "title": "Component"
          },
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "line_end": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last line (1-based, inclusive) of the hit, counted like line_start; None with it.",
            "title": "Line End"
          },
          "line_start": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "First line (1-based) of the hit in the text read-file returns for path and component; None when the producer did not place the hit in lines.",
            "title": "Line Start"
          },
          "locator": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "audio_range": "#/components/schemas/AudioRange",
                    "json_pointer": "#/components/schemas/JsonPointer",
                    "jsonl_record": "#/components/schemas/JsonlRecord",
                    "row_range": "#/components/schemas/RowRange",
                    "spreadsheet_range": "#/components/schemas/SpreadsheetRange",
                    "text_range": "#/components/schemas/TextRange",
                    "visual_region": "#/components/schemas/VisualRegion"
                  },
                  "propertyName": "kind"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/TextRange"
                  },
                  {
                    "$ref": "#/components/schemas/VisualRegion"
                  },
                  {
                    "$ref": "#/components/schemas/SpreadsheetRange"
                  },
                  {
                    "$ref": "#/components/schemas/JsonlRecord"
                  },
                  {
                    "$ref": "#/components/schemas/JsonPointer"
                  },
                  {
                    "$ref": "#/components/schemas/AudioRange"
                  },
                  {
                    "$ref": "#/components/schemas/RowRange"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the snippet sits, when the producer located it. None means the citation is component-level: ground the snippet against path (sheet=component for spreadsheets) to place it.",
            "title": "Locator"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The 1-based page the producer attributed the snippet to when it produced no locator; None when unknown or when the locator already carries the page.",
            "title": "Page"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "relevance_score": {
            "title": "Relevance Score",
            "type": "number"
          },
          "snippet": {
            "title": "Snippet",
            "type": "string"
          },
          "sql_table": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The run-sql table name holding the hit's component as rows (a spreadsheet tab's table, or a document's printed long tables); None when the component is not a table or the producer does not say.",
            "title": "Sql Table"
          },
          "why": {
            "description": "Which retrieval leg matched, or which graph path led here.",
            "title": "Why",
            "type": "string"
          }
        },
        "required": [
          "file_id",
          "path",
          "relevance_score",
          "snippet",
          "why"
        ],
        "title": "Evidence",
        "type": "object"
      },
      "ExternalWorkspaceStorage": {
        "additionalProperties": false,
        "properties": {
          "connection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Reusable storage connection bound permanently to this workspace; each workspace has its own exclusive namespace. Null when the caller cannot view the storage connection.",
            "title": "Connection Id"
          },
          "health": {
            "anyOf": [
              {
                "enum": [
                  "draft",
                  "ready",
                  "degraded",
                  "revoked"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current connection authorization state. Null when the caller cannot view the storage connection.",
            "title": "Health"
          },
          "location": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exclusive namespace containing this workspace's durable objects. Null when the caller cannot view the storage connection.",
            "title": "Location"
          },
          "provider": {
            "anyOf": [
              {
                "enum": [
                  "s3",
                  "azure_blob"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Customer object storage provider. Null when the caller cannot view the storage connection.",
            "title": "Provider"
          },
          "type": {
            "const": "external",
            "default": "external",
            "title": "Type",
            "type": "string"
          }
        },
        "title": "ExternalWorkspaceStorage",
        "type": "object"
      },
      "ExtractCitationOptions": {
        "additionalProperties": false,
        "properties": {
          "enabled": {
            "default": true,
            "description": "When true, each extracted field includes source locations.",
            "title": "Enabled",
            "type": "boolean"
          },
          "include_source_text": {
            "default": true,
            "description": "When true, citations include a short quote from the source alongside the location.",
            "title": "Include Source Text",
            "type": "boolean"
          }
        },
        "title": "ExtractCitationOptions",
        "type": "object"
      },
      "ExtractJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "extract",
            "default": "extract",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ndi_service__app__platform_api__results__ExtractResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present on succeeded while retained. Also present on a running extract job whose values were published before enrichment finished."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "ExtractJob",
        "type": "object"
      },
      "ExtractRequest": {
        "additionalProperties": false,
        "description": "Body for canonical ``POST /v1/extract`` (and the hidden legacy alias).\n\nExactly one of ``schema_id`` or ``schema`` is required. A legacy\n``json_schema`` alias is still accepted server-side for compatibility.\nOptional ``schema_version`` pins a registry version when ``schema_id`` is\nset; omit it to resolve latest. Accept-time freeze clears the wire\n``schema_id`` / ``schema_version``, stores the effective ``schema``, and\nrecords the resolved identity on ``resolved_schema_id`` /\n``resolved_schema_version`` for result audit metadata.",
        "properties": {
          "citations": {
            "$ref": "#/components/schemas/ExtractCitationOptions",
            "description": "Whether extracted fields include locations and quoted source text."
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "delivery": {
            "default": "complete",
            "description": "Progressive publishes extracted values on the running job before citation enrichment finishes. Poll GET /v1/jobs/{job_id} for the completed result; complete waits for all enrichment. Parquet currently returns only a complete result in either mode.",
            "enum": [
              "complete",
              "progressive"
            ],
            "title": "Delivery",
            "type": "string"
          },
          "instructions": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional guidance for how to fill the declared schema. Cannot add undeclared result fields.",
            "title": "Instructions"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive page ranges to extract. Omit to use the whole document.",
            "title": "Page Ranges"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the Parse that runs before this operation, using the same fields as Parse. Omit to use the default Parse. parse.parse_mode and the top-level parse_mode must agree when both are set, and so must parse.page_ranges and page_ranges. A setting that does not apply is reported in warnings."
          },
          "parse_mode": {
            "default": "low",
            "description": "How much parsing effort to use: Low uses native OCR, Medium routes to the best parser, and High adds page verification and correction.",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Parse Mode",
            "type": "string"
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "resolved_schema_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server-set at accept time when a registry schema_id was resolved.",
            "title": "Resolved Schema Id"
          },
          "resolved_schema_version": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server-set at accept time alongside resolved_schema_id.",
            "title": "Resolved Schema Version"
          },
          "schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Inline JSON Schema of fields to extract. Mutually exclusive with schema_id.",
            "title": "Schema"
          },
          "schema_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catalog schema family id (sch_...). Mutually exclusive with an inline schema.",
            "title": "Schema Id"
          },
          "schema_version": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pin a published catalog version. Omit with schema_id to use the latest version.",
            "title": "Schema Version"
          },
          "source": {
            "description": "The document to extract from: a fresh upload, an HTTPS URL, a workspace file, or a prior parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          }
        },
        "required": [
          "source"
        ],
        "title": "ExtractRequest",
        "type": "object"
      },
      "ExtractRequestEcho": {
        "additionalProperties": true,
        "type": "object"
      },
      "ExtractedField": {
        "additionalProperties": false,
        "description": "One field an extraction looked for.\n\n``not_found`` is a real outcome with an entry, not a missing key: an\nextraction that silently omits what it could not find is indistinguishable\nfrom one that never looked.",
        "properties": {
          "ambiguous": {
            "default": false,
            "description": "Whether multiple readings or an unsafe calculation prevent a unique verified value; see result warnings.",
            "title": "Ambiguous",
            "type": "boolean"
          },
          "citations": {
            "description": "Where the value was read. Empty when citations are off, the field was not found, or it is derived.",
            "items": {
              "$ref": "#/components/schemas/Citation"
            },
            "title": "Citations",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Evidence-support score for a found top-level scalar when the runtime produced one. Null for nested paths, arrays, not_found, derived, and unverifiable fields.",
            "title": "Confidence"
          },
          "derived": {
            "default": false,
            "description": "Whether this value was computed from source data rather than read directly. Derived values have no citations and a null confidence.",
            "title": "Derived",
            "type": "boolean"
          },
          "path": {
            "description": "JSON Pointer of this schema leaf (for example /invoice_number). Join key between data and fields.",
            "title": "Path",
            "type": "string"
          },
          "status": {
            "description": "Whether this leaf was filled: found has a value, not_found means the document was examined and the field is absent, ambiguous means a value is present but not unique.",
            "enum": [
              "found",
              "not_found",
              "ambiguous"
            ],
            "title": "Status",
            "type": "string"
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Extracted scalar for this path, or null when the field was not found.",
            "title": "Value"
          }
        },
        "required": [
          "path",
          "status"
        ],
        "title": "ExtractedField",
        "type": "object"
      },
      "ExtractionNullOnSuccessDisclosure": {
        "additionalProperties": false,
        "description": "Schema-required fields returned null because the document did not contain them.\n\nThe job succeeded. Null means the document was examined and the field\nwas absent — not that extraction failed or was skipped.",
        "properties": {
          "code": {
            "const": "extraction_null_on_success",
            "title": "Code",
            "type": "string"
          },
          "field_paths": {
            "description": "JSON paths of schema-required fields that were absent in the source document and returned as null.",
            "items": {
              "type": "string"
            },
            "title": "Field Paths",
            "type": "array"
          }
        },
        "required": [
          "code",
          "field_paths"
        ],
        "title": "ExtractionNullOnSuccessDisclosure",
        "type": "object"
      },
      "ExtractionSchema": {
        "additionalProperties": false,
        "description": "One immutable schema version, including the frozen JSON Schema body.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 2000,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "maxLength": 128,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "owner": {
            "enum": [
              "platform",
              "tenant"
            ],
            "title": "Owner",
            "type": "string"
          },
          "schema": {
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonValue"
            },
            "title": "Schema",
            "type": "object"
          },
          "schema_id": {
            "title": "Schema Id",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "version": {
            "minimum": 1.0,
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "schema_id",
          "name",
          "version",
          "owner",
          "created_at",
          "updated_at",
          "schema"
        ],
        "title": "ExtractionSchema",
        "type": "object"
      },
      "ExtractionSchemaSummary": {
        "additionalProperties": false,
        "description": "Latest visible version of one schema family.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "description": {
            "anyOf": [
              {
                "maxLength": 2000,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "name": {
            "maxLength": 128,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "owner": {
            "enum": [
              "platform",
              "tenant"
            ],
            "title": "Owner",
            "type": "string"
          },
          "schema_id": {
            "title": "Schema Id",
            "type": "string"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "version": {
            "minimum": 1.0,
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "schema_id",
          "name",
          "version",
          "owner",
          "created_at",
          "updated_at"
        ],
        "title": "ExtractionSchemaSummary",
        "type": "object"
      },
      "FactSearchRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /workspaces/{workspace_id}/fact-search`` — always the fixed pipeline.\n\nDeliberately no ``session_id``: a fact-search run is single-shot and keeps no\nconversation, so the strict base rejects the field outright instead of a\nbespoke validator explaining why it cannot be honored. No ``effort`` either —\nthe fixed pipeline has no budget presets. And no ``allow_clarification``: the\npipeline has no agent who could ask back, so it always answers — the strict\nbase rejects the field. ``include_answer`` is accepted and ignored only\nbecause published SDK releases still send it (see :data:`RetiredIncludeAnswer`).",
        "properties": {
          "context": {
            "anyOf": [
              {
                "maxLength": 20000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Free-form background for the model — the engagement, the entity, what the caller already knows. It informs the answer; it does not widen or narrow which files the caller may see.",
            "title": "Context"
          },
          "include_answer": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "deprecated": true,
            "description": "Deprecated and ignored: every run answers. Accepted so clients released before it was retired keep working; omit it.",
            "title": "Include Answer"
          },
          "path_prefix": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Put every uploaded file under one folder subtree, workspace-relative, in the run's scope; `paths`, where the body takes it, adds more files. Omit both for the whole workspace.",
            "title": "Path Prefix"
          },
          "paths": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 1024,
                  "minLength": 1,
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Scope the run to exactly these uploaded files. Every retrieval leg and agent tool sees only these files and the content ingested from them, so nothing else can be read or cited. Each entry names an uploaded source file (never a folder — scope folders with path_prefix; the two add up, so the run covers the folder's files plus these). No limit on how many. Unknown or inaccessible paths are refused up front.",
            "title": "Paths"
          },
          "query": {
            "description": "What to answer, in the caller's own words. Stripped before its length is checked; a blank query is refused rather than run.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "top_k": {
            "anyOf": [
              {
                "maximum": 50.0,
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How many evidences to return, best first. Omitted means 6. It is a cap on the answer's citation list, not on how much the pipeline reads: retrieval width is fixed, so a larger `top_k` returns more of what was already found rather than searching further. Raising it far above the default trades citation count for reliability — the whole list is one constrained generation, and the ceiling is 50.",
            "title": "Top K"
          }
        },
        "required": [
          "query"
        ],
        "title": "FactSearchRequest",
        "type": "object"
      },
      "FieldReadability": {
        "additionalProperties": false,
        "description": "How much of one filtered field the extraction could actually read.\n\nOnly a ``found`` observation materializes a value, so a comparison against a\nfield the extraction did not resolve silently drops those components: the\nquery is correct and the result is empty for a reason that has nothing to do\nwith the caller's question. Reported per field the query filtered on, and\nonly when ``readable < in_scope`` — a fully readable field says nothing.\n\nRead it with ``total_matches``: when ``readable`` is 0 the empty result\ncarries no information about the population, and when the unreadable\nremainder is large next to ``total_matches`` the matches shown are a floor,\nnot a census.",
        "properties": {
          "field": {
            "description": "The extracted field the query filtered on.",
            "title": "Field",
            "type": "string"
          },
          "in_scope": {
            "description": "Components in scope whose document type carries this field.",
            "title": "In Scope",
            "type": "integer"
          },
          "readable": {
            "description": "Of those, how many had a resolved value the predicate could evaluate.",
            "title": "Readable",
            "type": "integer"
          }
        },
        "required": [
          "field",
          "in_scope",
          "readable"
        ],
        "title": "FieldReadability",
        "type": "object"
      },
      "File": {
        "additionalProperties": false,
        "description": "A source file. The derived tree is platform-owned and has no CRUD surface.",
        "properties": {
          "access_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly one label, or null when the workspace declares none.",
            "title": "Access Label"
          },
          "access_label_source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AccessLabelSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null until categorised.",
            "title": "Category"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When derived material for this file ages out.",
            "title": "Expires At"
          },
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "file_name": {
            "description": "The last segment of `path`, for display only. A tool given it as `path` answers file_not_found.",
            "title": "File Name",
            "type": "string"
          },
          "file_type": {
            "title": "File Type",
            "type": "string"
          },
          "graph_inclusion": {
            "default": "auto",
            "description": "This file's knowledge-graph inclusion policy, not its effective membership. 'auto' defers to the workspace's KG exclusion rules; 'include'/'exclude' override them for this one file. A file excluded by a workspace rule still reads 'auto' here, so this does not on its own tell an excluded file from one whose graph is not built yet — read representations.knowledge_graph for whether a build has covered it.",
            "enum": [
              "auto",
              "include",
              "exclude"
            ],
            "title": "Graph Inclusion",
            "type": "string"
          },
          "ingested_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ingested At"
          },
          "ingested_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Content hash at the last successful ingestion. Null with ingested_at means never ingested.",
            "title": "Ingested Hash"
          },
          "ingestion_status": {
            "$ref": "#/components/schemas/IngestionStatus"
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Caller-supplied metadata.",
            "title": "Labels",
            "type": "object"
          },
          "observed_hash": {
            "title": "Observed Hash",
            "type": "string"
          },
          "path": {
            "description": "Full path relative to the workspace root. Send this exact string wherever a tool takes `path`: tools match it exactly.",
            "title": "Path",
            "type": "string"
          },
          "size_bytes": {
            "title": "Size Bytes",
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "version": {
            "description": "Starts at 1; increments on every content replacement.",
            "title": "Version",
            "type": "integer"
          },
          "workspace_id": {
            "format": "uuid",
            "title": "Workspace Id",
            "type": "string"
          }
        },
        "required": [
          "file_id",
          "workspace_id",
          "path",
          "file_name",
          "file_type",
          "size_bytes",
          "observed_hash",
          "ingestion_status",
          "version",
          "created_at",
          "updated_at"
        ],
        "title": "File",
        "type": "object"
      },
      "FileCategoryAssignment": {
        "additionalProperties": false,
        "properties": {
          "category": {
            "title": "Category",
            "type": "string"
          },
          "is_freeform_subcategory": {
            "default": false,
            "title": "Is Freeform Subcategory",
            "type": "boolean"
          },
          "subcategory": {
            "title": "Subcategory",
            "type": "string"
          }
        },
        "required": [
          "category",
          "subcategory"
        ],
        "title": "FileCategoryAssignment",
        "type": "object"
      },
      "FileComponentInfo": {
        "additionalProperties": false,
        "description": "One part of an uploaded file that can be asked about by name: a document\nsection, a spreadsheet tab, an image, or the raw upload itself.",
        "properties": {
          "categories": {
            "description": "Category/subcategory paths assigned to this section or tab at ingestion.",
            "items": {
              "type": "string"
            },
            "title": "Categories",
            "type": "array"
          },
          "column_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Columns in the component's table, when it has one.",
            "title": "Column Count"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why ingestion could not read this component; it stays listed but has no content. `not_queryable:<code>` instead means the tab is still readable as text but is not a table query-tables can read; the code names the reason and never quotes cells. `ledger_structure_not_recognized:<code>` means structured ledger extraction failed but the tab is still queryable as a raw grid (columns A, B, ...; every populated row is data).",
            "title": "Error"
          },
          "key_terms": {
            "description": "Up to FILE_METADATA_MAX_KEY_TERMS of the component's extracted keywords whose role the source states (who a name is, what a date or number marks), in extraction order. Empty for files ingested before keyword roles were extracted.",
            "items": {
              "$ref": "#/components/schemas/FileKeywordDescription"
            },
            "maxItems": 6,
            "title": "Key Terms",
            "type": "array"
          },
          "kind": {
            "description": "What the component is: a document `section`, a spreadsheet `tab`, an `image`, or the `raw` file.",
            "enum": [
              "section",
              "tab",
              "image",
              "raw"
            ],
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "description": "The component's name — pass it as `component` to scope a question; empty when the whole file is the unit.",
            "title": "Name",
            "type": "string"
          },
          "page_end": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last source page covered, 1-based (sections).",
            "title": "Page End"
          },
          "page_start": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "First source page covered, 1-based (sections).",
            "title": "Page Start"
          },
          "queryable": {
            "description": "True when the component is a table that query-tables can compute over.",
            "title": "Queryable",
            "type": "boolean"
          },
          "readable": {
            "description": "True when the component has text a question about the file can be answered from.",
            "title": "Readable",
            "type": "boolean"
          },
          "row_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Tabs: rows in the queryable table, null when the tab is not queryable; sections: rows in their rows tables; else the source extent.",
            "title": "Row Count"
          },
          "summary": {
            "default": "",
            "description": "What the component contains, as summarized at ingestion.",
            "title": "Summary",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "name",
          "readable",
          "queryable"
        ],
        "title": "FileComponentInfo",
        "type": "object"
      },
      "FileDeletionOutcome": {
        "additionalProperties": false,
        "description": "One requested file's fate, decided when the batch was accepted.\n\nPer-file rather than a single verdict, for the reason an ingestion reports\nper-file outcomes: an id that no longer resolves, or one the caller may not\nsee, must not fail the other files in the batch.",
        "properties": {
          "file_id": {
            "description": "The requested file, echoed whether or not it was deleted.",
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The deleted file's workspace-relative path; null when the id resolved to no visible file.",
            "title": "Path"
          },
          "status": {
            "description": "Whether this file was soft-deleted, did not exist in the workspace, or was withheld by the access gate.",
            "enum": [
              "deleted",
              "not_found",
              "access_denied"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "file_id",
          "status"
        ],
        "title": "FileDeletionOutcome",
        "type": "object"
      },
      "FileDetail": {
        "additionalProperties": false,
        "description": "A source file plus short-lived presigned URLs for its bytes.\n\nNo separate ``GET .../content`` route: a presigned URL keeps raw bytes\noff the API path and avoids charging for a second network hop inside the\nplatform.  Both URLs expire after ``DOWNLOAD_URL_TTL_SECONDS`` seconds;\nfetch them promptly.\n\nThe two differ only in the response headers S3 returns: ``download_url``\nsaves to disk, ``preview_url`` renders in place under the file's real\nmedia type.  One URL cannot do both — a browser decides from the headers.",
        "properties": {
          "access_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exactly one label, or null when the workspace declares none.",
            "title": "Access Label"
          },
          "access_label_source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AccessLabelSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null until categorised.",
            "title": "Category"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "download_url": {
            "description": "Time-limited presigned GET URL that saves the file's bytes to disk.",
            "title": "Download Url",
            "type": "string"
          },
          "download_url_expires_at": {
            "description": "When the presigned URLs stop being valid.",
            "format": "date-time",
            "title": "Download Url Expires At",
            "type": "string"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When derived material for this file ages out.",
            "title": "Expires At"
          },
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "file_name": {
            "description": "The last segment of `path`, for display only. A tool given it as `path` answers file_not_found.",
            "title": "File Name",
            "type": "string"
          },
          "file_type": {
            "title": "File Type",
            "type": "string"
          },
          "graph_inclusion": {
            "default": "auto",
            "description": "This file's knowledge-graph inclusion policy, not its effective membership. 'auto' defers to the workspace's KG exclusion rules; 'include'/'exclude' override them for this one file. A file excluded by a workspace rule still reads 'auto' here, so this does not on its own tell an excluded file from one whose graph is not built yet — read representations.knowledge_graph for whether a build has covered it.",
            "enum": [
              "auto",
              "include",
              "exclude"
            ],
            "title": "Graph Inclusion",
            "type": "string"
          },
          "ingested_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ingested At"
          },
          "ingested_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Content hash at the last successful ingestion. Null with ingested_at means never ingested.",
            "title": "Ingested Hash"
          },
          "ingestion_status": {
            "$ref": "#/components/schemas/IngestionStatus"
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Caller-supplied metadata.",
            "title": "Labels",
            "type": "object"
          },
          "observed_hash": {
            "title": "Observed Hash",
            "type": "string"
          },
          "path": {
            "description": "Full path relative to the workspace root. Send this exact string wherever a tool takes `path`: tools match it exactly.",
            "title": "Path",
            "type": "string"
          },
          "preview_url": {
            "description": "Time-limited presigned GET URL that a browser renders inline.",
            "title": "Preview Url",
            "type": "string"
          },
          "size_bytes": {
            "title": "Size Bytes",
            "type": "integer"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "version": {
            "description": "Starts at 1; increments on every content replacement.",
            "title": "Version",
            "type": "integer"
          },
          "workspace_id": {
            "format": "uuid",
            "title": "Workspace Id",
            "type": "string"
          }
        },
        "required": [
          "file_id",
          "workspace_id",
          "path",
          "file_name",
          "file_type",
          "size_bytes",
          "observed_hash",
          "ingestion_status",
          "version",
          "created_at",
          "updated_at",
          "download_url",
          "preview_url",
          "download_url_expires_at"
        ],
        "title": "FileDetail",
        "type": "object"
      },
      "FileDocumentMetadata": {
        "additionalProperties": false,
        "properties": {
          "access_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Label"
          },
          "access_label_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Label Reason"
          },
          "access_label_source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AccessLabelSource"
              },
              {
                "type": "null"
              }
            ]
          },
          "category": {
            "title": "Category",
            "type": "string"
          },
          "char_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Characters in the segment's markdown; null on older ingests.",
            "title": "Char Count"
          },
          "is_freeform_subcategory": {
            "default": false,
            "title": "Is Freeform Subcategory",
            "type": "boolean"
          },
          "keyword_descriptions": {
            "description": "Context for each document keyword when generated.",
            "items": {
              "$ref": "#/components/schemas/FileKeywordDescription"
            },
            "title": "Keyword Descriptions",
            "type": "array"
          },
          "keywords": {
            "items": {
              "type": "string"
            },
            "title": "Keywords",
            "type": "array"
          },
          "page_end": {
            "title": "Page End",
            "type": "integer"
          },
          "page_start": {
            "title": "Page Start",
            "type": "integer"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "subcategory": {
            "title": "Subcategory",
            "type": "string"
          },
          "summary": {
            "title": "Summary",
            "type": "string"
          }
        },
        "required": [
          "category",
          "subcategory",
          "summary",
          "page_start",
          "page_end",
          "path"
        ],
        "title": "FileDocumentMetadata",
        "type": "object"
      },
      "FileFigureInfo": {
        "additionalProperties": false,
        "description": "One picture inside a PDF page — a seal, chart, photo, map or stamp that OCR found as a region.\n\nIts description is also inline in read-file (``[figure pN-K: …]`` at its spot on the page)\nand in hybrid-search, so a figure can be found by what it shows.",
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the figure shows, written by a vision model at ingestion; null when not described.",
            "title": "Description"
          },
          "name": {
            "description": "`figure p<page>-<n>`. Pass it as qa-file's `component` to ask the vision engine about this figure alone.",
            "title": "Name",
            "type": "string"
          },
          "page": {
            "description": "1-based page the figure is on.",
            "title": "Page",
            "type": "integer"
          },
          "text": {
            "default": "",
            "description": "Text printed inside the figure, as OCR read it.",
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "name",
          "page"
        ],
        "title": "FileFigureInfo",
        "type": "object"
      },
      "FileIdsSelection": {
        "additionalProperties": false,
        "description": "One file or an explicit batch.",
        "properties": {
          "file_ids": {
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "maxItems": 1000,
            "minItems": 1,
            "title": "File Ids",
            "type": "array"
          },
          "type": {
            "const": "file_ids",
            "default": "file_ids",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "file_ids"
        ],
        "title": "FileIdsSelection",
        "type": "object"
      },
      "FileKeywordDescription": {
        "additionalProperties": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "type": "object"
      },
      "FileListPage": {
        "additionalProperties": false,
        "description": "A page of source files plus the access honesty block.\n\n``coverage`` reports how many candidates the access gate withheld and\nwhich labels would have been needed to see them.  A workspace that\ndeclares no access labels always has an empty ``coverage``; ``total_count``\nis always exact after filtering.",
        "properties": {
          "coverage": {
            "$ref": "#/components/schemas/Coverage"
          },
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/File"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "FileListPage",
        "type": "object"
      },
      "FileMarlinEvent": {
        "additionalProperties": false,
        "properties": {
          "end_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Ms"
          },
          "start_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start Ms"
          },
          "text": {
            "default": "",
            "title": "Text",
            "type": "string"
          }
        },
        "title": "FileMarlinEvent",
        "type": "object"
      },
      "FileMediaMetadata": {
        "additionalProperties": false,
        "properties": {
          "duration_ms": {
            "title": "Duration Ms",
            "type": "integer"
          },
          "frame_count": {
            "default": 0,
            "title": "Frame Count",
            "type": "integer"
          },
          "frames_dir": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Frames Dir"
          },
          "keywords": {
            "items": {
              "type": "string"
            },
            "title": "Keywords",
            "type": "array"
          },
          "marlin_events": {
            "items": {
              "$ref": "#/components/schemas/FileMarlinEvent"
            },
            "title": "Marlin Events",
            "type": "array"
          },
          "marlin_summary": {
            "default": "",
            "title": "Marlin Summary",
            "type": "string"
          },
          "modality": {
            "enum": [
              "audio",
              "video"
            ],
            "title": "Modality",
            "type": "string"
          },
          "speakers": {
            "items": {
              "$ref": "#/components/schemas/FileMediaSpeaker"
            },
            "title": "Speakers",
            "type": "array"
          },
          "speech_segment_count": {
            "default": 0,
            "title": "Speech Segment Count",
            "type": "integer"
          },
          "summary": {
            "default": "",
            "title": "Summary",
            "type": "string"
          },
          "timeline_path": {
            "title": "Timeline Path",
            "type": "string"
          },
          "transcript_path": {
            "title": "Transcript Path",
            "type": "string"
          }
        },
        "required": [
          "modality",
          "duration_ms",
          "timeline_path",
          "transcript_path"
        ],
        "title": "FileMediaMetadata",
        "type": "object"
      },
      "FileMediaSpeaker": {
        "additionalProperties": false,
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label"
          }
        },
        "required": [
          "id"
        ],
        "title": "FileMediaSpeaker",
        "type": "object"
      },
      "FileMetadata": {
        "additionalProperties": false,
        "description": "Ingestion-derived metadata for a source file.\n\n``representations`` answers \"is this file actually searchable right now\",\nwhich ``ingestion_status`` alone cannot: a file can be ingested while its\ngraph generation is still building.\n\n``outputs`` lists every live derivation (``retired_at IS NULL``) so a\ncaller knows exactly what exists at each instant without racing against a\nre-ingestion in progress.",
        "properties": {
          "documents": {
            "items": {
              "$ref": "#/components/schemas/FileDocumentMetadata"
            },
            "title": "Documents",
            "type": "array"
          },
          "duration_ms": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "For audio/video; null for document formats.",
            "title": "Duration Ms"
          },
          "extracted_fields": {
            "items": {
              "$ref": "#/components/schemas/ExtractedField"
            },
            "title": "Extracted Fields",
            "type": "array"
          },
          "file": {
            "$ref": "#/components/schemas/File"
          },
          "keyword_descriptions": {
            "description": "One source-grounded explanation per file keyword, when generated.",
            "items": {
              "$ref": "#/components/schemas/FileKeywordDescription"
            },
            "title": "Keyword Descriptions",
            "type": "array"
          },
          "keywords": {
            "description": "Lane-level keywords extracted during ingestion.",
            "items": {
              "type": "string"
            },
            "title": "Keywords",
            "type": "array"
          },
          "lane": {
            "description": "Which ingestion lane processed this file.",
            "title": "Lane",
            "type": "string"
          },
          "last_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "The most recent ingestion error, if any."
          },
          "media": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FileMediaMetadata"
              },
              {
                "type": "null"
              }
            ]
          },
          "native_metadata": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NativeFileMetadata"
              },
              {
                "type": "null"
              }
            ],
            "description": "Source filesystem time and format-native properties captured during ingestion."
          },
          "outputs": {
            "items": {
              "$ref": "#/components/schemas/ArtifactOutputRef"
            },
            "title": "Outputs",
            "type": "array"
          },
          "page_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "For document formats; null for spreadsheets and media.",
            "title": "Page Count"
          },
          "read_coverage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FileReadCoverage"
              },
              {
                "type": "null"
              }
            ],
            "description": "Recorded page reads and OCR usage for the published generation; null when provenance is unavailable."
          },
          "representations": {
            "$ref": "#/components/schemas/RepresentationState"
          },
          "sheet_names": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "For workbook formats; null for everything else.",
            "title": "Sheet Names"
          },
          "sheets": {
            "items": {
              "$ref": "#/components/schemas/FileSheetMetadata"
            },
            "title": "Sheets",
            "type": "array"
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Lane-level summary extracted during ingestion.",
            "title": "Summary"
          }
        },
        "required": [
          "file",
          "lane"
        ],
        "title": "FileMetadata",
        "type": "object"
      },
      "FileMetadataRequest": {
        "additionalProperties": false,
        "description": "Request body for ``file-metadata``. ``path`` names one uploaded file.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Describe only this section or tab, named exactly as an unscoped call lists it.",
            "title": "Component"
          },
          "path": {
            "description": "The uploaded file's full path relative to the workspace root, exactly as it was uploaded and as listings and search results print it — e.g. `evidence/doc-7f83/contract.pdf`. Not a bare file name (a file's `file_name`), a folder, a file id, or a path that starts with the workspace id.",
            "maxLength": 1024,
            "minLength": 1,
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "FileMetadataRequest",
        "type": "object"
      },
      "FileMetadataResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "$ref": "#/components/schemas/FileMetadataToolResponse",
            "description": "The operation response returned to the caller, retained with its job."
          },
          "result_type": {
            "const": "file_metadata",
            "default": "file_metadata",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "output"
        ],
        "title": "FileMetadataResult",
        "type": "object"
      },
      "FileMetadataToolResponse": {
        "additionalProperties": false,
        "description": "Response body for ``file-metadata`` — what one uploaded file is, without opening it.\n\n``summary`` is the summary of the file's first section or tab, never a\nconcatenation across components (each component carries its own). A file\nthat is not ingested yet answers 200 with its ``ingestion_status`` and no\ncomponents; a failed one also carries ``ingestion_error``.",
        "properties": {
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The file's primary category path, when classified.",
            "title": "Category"
          },
          "components": {
            "description": "The file's sections, tabs, image or recording, in reading order.",
            "items": {
              "discriminator": {
                "mapping": {
                  "image": "#/components/schemas/FileComponentInfo",
                  "media": "#/components/schemas/MediaComponentInfo",
                  "raw": "#/components/schemas/FileComponentInfo",
                  "section": "#/components/schemas/FileComponentInfo",
                  "tab": "#/components/schemas/FileComponentInfo"
                },
                "propertyName": "kind"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/FileComponentInfo"
                },
                {
                  "$ref": "#/components/schemas/MediaComponentInfo"
                }
              ]
            },
            "title": "Components",
            "type": "array"
          },
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "figures": {
            "description": "PDFs: pictures inside the pages (seals, charts, photos, stamps), in page order; with `component`, only those on that component's pages. Empty for other files and for PDFs ingested before figures were recorded.",
            "items": {
              "$ref": "#/components/schemas/FileFigureInfo"
            },
            "title": "Figures",
            "type": "array"
          },
          "file_id": {
            "description": "The uploaded file's id, as the files endpoints address it.",
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "ingestion_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why ingestion failed, when the ledger recorded a reason.",
            "title": "Ingestion Error"
          },
          "ingestion_status": {
            "$ref": "#/components/schemas/IngestionStatus",
            "description": "Where the file is in ingestion; a file that is not `ingested` has no components yet."
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The external operation job; absent for commands inside a search job.",
            "title": "Job Id"
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ingestion lane (document / table / media), when known.",
            "title": "Kind"
          },
          "page_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pages in a paged document; absent for other files.",
            "title": "Page Count"
          },
          "path": {
            "description": "The uploaded file's path relative to the workspace root, as requested.",
            "title": "Path",
            "type": "string"
          },
          "read_coverage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FileReadCoverage"
              },
              {
                "type": "null"
              }
            ],
            "description": "Recorded page reads and OCR usage for the published generation; absent when provenance is unavailable."
          },
          "size_bytes": {
            "description": "Byte size of the uploaded source object.",
            "title": "Size Bytes",
            "type": "integer"
          },
          "summary": {
            "default": "",
            "description": "Summary of the file's first section or tab; each component has its own.",
            "title": "Summary",
            "type": "string"
          },
          "tab_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Tabs in a workbook; absent for other files.",
            "title": "Tab Count"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "path",
          "file_id",
          "ingestion_status",
          "size_bytes"
        ],
        "title": "FileMetadataToolResponse",
        "type": "object"
      },
      "FileQueryScope": {
        "additionalProperties": false,
        "description": "The question ran against one workspace-relative file.",
        "properties": {
          "path": {
            "maxLength": 1024,
            "minLength": 1,
            "title": "Path",
            "type": "string"
          },
          "type": {
            "const": "file",
            "default": "file",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "FileQueryScope",
        "type": "object"
      },
      "FileReadCoverage": {
        "additionalProperties": false,
        "description": "Recorded read outcomes for the last published ingestion generation.",
        "properties": {
          "ocr_used": {
            "description": "Whether OCR produced this generation's parsed content.",
            "title": "Ocr Used",
            "type": "boolean"
          },
          "pages_failed": {
            "description": "Pages whose read failed; whole-parse failures appear as ingestion errors.",
            "minimum": 0.0,
            "title": "Pages Failed",
            "type": "integer"
          },
          "pages_read": {
            "description": "Pages successfully read for this generation.",
            "minimum": 0.0,
            "title": "Pages Read",
            "type": "integer"
          }
        },
        "required": [
          "pages_read",
          "pages_failed",
          "ocr_used"
        ],
        "title": "FileReadCoverage",
        "type": "object"
      },
      "FileSheetMetadata": {
        "additionalProperties": false,
        "properties": {
          "categories": {
            "items": {
              "$ref": "#/components/schemas/FileCategoryAssignment"
            },
            "title": "Categories",
            "type": "array"
          },
          "char_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Characters in the tab's markdown; null on older ingests.",
            "title": "Char Count"
          },
          "column_count": {
            "default": 0,
            "title": "Column Count",
            "type": "integer"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "jsonl_path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Jsonl Path"
          },
          "keyword_descriptions": {
            "description": "Context for each sheet keyword when generated.",
            "items": {
              "$ref": "#/components/schemas/FileKeywordDescription"
            },
            "title": "Keyword Descriptions",
            "type": "array"
          },
          "keywords": {
            "items": {
              "type": "string"
            },
            "title": "Keywords",
            "type": "array"
          },
          "markdown_path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Markdown Path"
          },
          "max_column": {
            "default": 0,
            "title": "Max Column",
            "type": "integer"
          },
          "max_row": {
            "default": 0,
            "title": "Max Row",
            "type": "integer"
          },
          "non_empty_cell_count": {
            "default": 0,
            "title": "Non Empty Cell Count",
            "type": "integer"
          },
          "parquet_path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parquet Path"
          },
          "queryable": {
            "default": false,
            "description": "Whether the tab's rows are a table run-sql can query. A CSV tab is stored as a partitioned dataset, so it is queryable while jsonl_path and parquet_path are both null.",
            "title": "Queryable",
            "type": "boolean"
          },
          "row_count": {
            "default": 0,
            "title": "Row Count",
            "type": "integer"
          },
          "sheet_name": {
            "title": "Sheet Name",
            "type": "string"
          },
          "summary": {
            "default": "",
            "title": "Summary",
            "type": "string"
          },
          "table_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The name run-sql registers the tab under, for a workbook tab or a converted CSV. Null when the tab is not queryable, or when the name is not recorded here (for example a directly uploaded parquet); file-metadata and locate publish the registered name, which may carry a suffix that keeps names unique.",
            "title": "Table Name"
          }
        },
        "required": [
          "sheet_name"
        ],
        "title": "FileSheetMetadata",
        "type": "object"
      },
      "FileVersion": {
        "additionalProperties": false,
        "description": "Metadata only. Retaining every superseded copy is a customer opt-in.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "ingested_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ingested At"
          },
          "ingested_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ingested Hash"
          },
          "is_current": {
            "title": "Is Current",
            "type": "boolean"
          },
          "observed_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Observed Hash"
          },
          "replaced_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Null on the current version.",
            "title": "Replaced At"
          },
          "size_bytes": {
            "title": "Size Bytes",
            "type": "integer"
          },
          "version": {
            "title": "Version",
            "type": "integer"
          }
        },
        "required": [
          "version",
          "size_bytes",
          "created_at",
          "is_current"
        ],
        "title": "FileVersion",
        "type": "object"
      },
      "FilesQueryScope": {
        "additionalProperties": false,
        "description": "The question ran against several files; only the count is public.",
        "properties": {
          "count": {
            "minimum": 2.0,
            "title": "Count",
            "type": "integer"
          },
          "type": {
            "const": "files",
            "default": "files",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "count"
        ],
        "title": "FilesQueryScope",
        "type": "object"
      },
      "FilteredSearchCell": {
        "additionalProperties": false,
        "description": "One extracted field value on one row, with its evidence (D10).\n\n``status`` is value-level data honesty: ``not_found`` means the component\nwas examined and the field is absent; ``ambiguous`` means present but not\nnormalizable (e.g. money without a currency); ``unexamined`` means the\nextraction could not say.",
        "properties": {
          "citation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Citation"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the value was found, with quoted source text."
          },
          "field": {
            "title": "Field",
            "type": "string"
          },
          "item_index": {
            "default": 0,
            "description": "Position for repeated fields; 0 for scalars.",
            "title": "Item Index",
            "type": "integer"
          },
          "native_display": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The source cell's formatted display, when available, kept separately from its typed value.",
            "title": "Native Display"
          },
          "native_raw": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The stored native cell value, before display formatting or rounding.",
            "title": "Native Raw"
          },
          "status": {
            "enum": [
              "found",
              "not_found",
              "ambiguous",
              "unexamined"
            ],
            "title": "Status",
            "type": "string"
          },
          "value": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "boolean": "#/components/schemas/BooleanCell",
                    "date": "#/components/schemas/DateCell",
                    "money": "#/components/schemas/MoneyCell",
                    "number": "#/components/schemas/NumberCell",
                    "text": "#/components/schemas/TextCell"
                  },
                  "propertyName": "kind"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/MoneyCell"
                  },
                  {
                    "$ref": "#/components/schemas/TextCell"
                  },
                  {
                    "$ref": "#/components/schemas/DateCell"
                  },
                  {
                    "$ref": "#/components/schemas/NumberCell"
                  },
                  {
                    "$ref": "#/components/schemas/BooleanCell"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Value"
          }
        },
        "required": [
          "field",
          "status"
        ],
        "title": "FilteredSearchCell",
        "type": "object"
      },
      "FilteredSearchComponent": {
        "additionalProperties": false,
        "description": "A matching component and its own observations within an uploaded file.",
        "properties": {
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The component's primary taxonomy category.",
            "title": "Category"
          },
          "cells": {
            "description": "Typed observations belonging to this component.",
            "items": {
              "$ref": "#/components/schemas/FilteredSearchCell"
            },
            "title": "Cells",
            "type": "array"
          },
          "component": {
            "description": "Public component name — the tab or document section, matching the component= argument of the file tools (qa-file, read-file, query-tables). Several document rows can share one section name; page_start/page_end distinguish them. A media row's name is the recording stem, display-only (file tools take the whole file).",
            "title": "Component",
            "type": "string"
          },
          "component_kind": {
            "description": "The representation containing these observations.",
            "enum": [
              "document",
              "sheet",
              "media"
            ],
            "title": "Component Kind",
            "type": "string"
          },
          "content_matches": {
            "description": "Content criteria this row satisfied, with observed values and the source passages used to verify them.",
            "items": {
              "$ref": "#/components/schemas/ContentConditionMatch"
            },
            "title": "Content Matches",
            "type": "array"
          },
          "document_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The profiled document type of this component.",
            "title": "Document Type"
          },
          "entity_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The printed identifier of the matching entity within a register.",
            "title": "Entity Id"
          },
          "page_end": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last source page containing the component.",
            "title": "Page End"
          },
          "page_start": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "First source page containing the component.",
            "title": "Page Start"
          },
          "source_row": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The native sheet row containing this entity's facts.",
            "title": "Source Row"
          },
          "subcategory": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The component's primary taxonomy subcategory.",
            "title": "Subcategory"
          },
          "summary": {
            "default": "",
            "description": "A description of the component's contents.",
            "title": "Summary",
            "type": "string"
          }
        },
        "required": [
          "component",
          "component_kind"
        ],
        "title": "FilteredSearchComponent",
        "type": "object"
      },
      "FilteredSearchJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "filtered_search",
            "default": "filtered_search",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FilteredSearchResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "FilteredSearchJob",
        "type": "object"
      },
      "FilteredSearchPage": {
        "additionalProperties": false,
        "description": "Fetch the next page of an earlier filtered search — live re-execution, no agent.",
        "properties": {
          "cursor": {
            "description": "The `next_cursor` of an earlier filtered-search result, exactly as received.",
            "maxLength": 512,
            "minLength": 1,
            "title": "Cursor",
            "type": "string"
          },
          "type": {
            "const": "page",
            "default": "page",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "cursor"
        ],
        "title": "FilteredSearchPage",
        "type": "object"
      },
      "FilteredSearchResult": {
        "additionalProperties": false,
        "description": "The typed outcome of one filtered-search execution (or one page of it).\n\n``exhaustive`` is the coarse completeness signal: when it is false, returned\nmatches are valid, but \"all\"-style claims, ``total_matches`` as a census,\nand zero-match conclusions are not guaranteed. It is scope-wide and\nall-or-nothing, so it cannot say *what* was incomplete;\n``field_readability`` is its per-field companion, naming the filtered\nfields the extraction could not fully read — the difference between \"no\ncomponent matched\" and \"the column you filtered on was largely unreadable\".\nPagination is LIVE — each page re-executes against the current catalog, so\nconcurrent ingestion, deletion, or relabeling may shift later pages (rows\ncan repeat or be skipped across page boundaries); ``catalog_drifted`` says\nthe scope changed since the query was first validated.",
        "properties": {
          "applied_query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server-rendered display form of the published query.",
            "title": "Applied Query"
          },
          "candidates_seen": {
            "default": 0,
            "title": "Candidates Seen",
            "type": "integer"
          },
          "catalog_drifted": {
            "default": false,
            "description": "The catalog changed since the query was validated.",
            "title": "Catalog Drifted",
            "type": "boolean"
          },
          "clarification": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Non-null exactly when the run asked a clarifying question instead of executing — only possible when the initial query set `allow_clarification`: no rows, no applied_query, exhaustive false. Filtered search keeps no session; answer it by issuing a new initial query.",
            "title": "Clarification"
          },
          "columns": {
            "items": {
              "$ref": "#/components/schemas/CatalogColumnDescriptor"
            },
            "title": "Columns",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The agent's self-graded confidence in the published result — how well the catalog evidence supports its reading of the request, on the shared six-level scale (certain / very_high / high / medium / low / speculative). Null on runs rejected with a `clarification`, on page requests, and on results stored before the field existed."
          },
          "content_evidences": {
            "description": "Residual content condition passages, server-verified; present only on residual queries.",
            "items": {
              "$ref": "#/components/schemas/ContentEvidence"
            },
            "title": "Content Evidences",
            "type": "array"
          },
          "content_verification": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ContentVerificationSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "Coverage of the content criterion check. Null for pure catalog queries and older results. An empty result with unverified candidates does not establish that no documents match."
          },
          "coverage": {
            "$ref": "#/components/schemas/Coverage"
          },
          "evidences": {
            "description": "Referent-resolution evidence: the file passages that turned a role or relative referent in the query ('the CEO') into the concrete filter value the published query uses. Agent-cited, then resolved server-side to the caller's own uploaded file exactly like search evidence — an entry that cannot be resolved to a visible file is dropped, never published. Distinct from content_evidences, which are server-verified residual matches. Empty on pure catalog queries.",
            "items": {
              "$ref": "#/components/schemas/SearchEvidence"
            },
            "title": "Evidences",
            "type": "array"
          },
          "executed_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When this page's snapshot was read.",
            "title": "Executed At"
          },
          "exhausted": {
            "default": false,
            "description": "Step budget hit before the agent finished. A success, not a failure.",
            "title": "Exhausted",
            "type": "boolean"
          },
          "exhaustive": {
            "default": false,
            "description": "True only when every eligible component was completely cataloged and evaluated — the scope-wide completeness signal. False whenever coverage is partial or a residual content condition was applied.",
            "title": "Exhaustive",
            "type": "boolean"
          },
          "field_readability": {
            "description": "Filtered fields the extraction could not fully read, server-computed. An empty list is an answer — every field the query filtered on was fully readable — rather than an omission.",
            "items": {
              "$ref": "#/components/schemas/FieldReadability"
            },
            "title": "Field Readability",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque cursor for the next page — POST it back as {type: 'page', cursor}. Null on the last page.",
            "title": "Next Cursor"
          },
          "result_type": {
            "const": "filtered_search",
            "default": "filtered_search",
            "title": "Result Type",
            "type": "string"
          },
          "result_unit": {
            "default": "component",
            "description": "The unit used for rows, totals, top-N and pagination. New searches consistently return catalog entries with their established identities. Legacy units remain readable.",
            "enum": [
              "source",
              "component",
              "entity",
              "entry"
            ],
            "title": "Result Unit",
            "type": "string"
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/FilteredSearchRow"
            },
            "title": "Rows",
            "type": "array"
          },
          "steps_used": {
            "default": 0,
            "title": "Steps Used",
            "type": "integer"
          },
          "tool_calls": {
            "items": {
              "$ref": "#/components/schemas/ToolCallTrace"
            },
            "title": "Tool Calls",
            "type": "array"
          },
          "total_files": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Distinct source files supporting the confirmed matches before any page or top-N cut. Null for older results or when no authoritative selection was executed. Subject to the same completeness as total_matches.",
            "title": "Total Files"
          },
          "total_matches": {
            "default": 0,
            "description": "Confirmed matches in result_unit, before any page or top-N cut.",
            "title": "Total Matches",
            "type": "integer"
          },
          "truncated": {
            "default": false,
            "description": "A structural cap degraded this result; matches shown remain valid.",
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "title": "FilteredSearchResult",
        "type": "object"
      },
      "FilteredSearchRow": {
        "additionalProperties": false,
        "description": "One catalog entry, or a historical result, with its supporting evidence.",
        "properties": {
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The component's primary taxonomy category.",
            "title": "Category"
          },
          "cells": {
            "description": "Typed observations belonging to this component.",
            "items": {
              "$ref": "#/components/schemas/FilteredSearchCell"
            },
            "title": "Cells",
            "type": "array"
          },
          "component": {
            "description": "Public component name — the tab or document section, matching the component= argument of the file tools (qa-file, read-file, query-tables). Several document rows can share one section name; page_start/page_end distinguish them. A media row's name is the recording stem, display-only (file tools take the whole file).",
            "title": "Component",
            "type": "string"
          },
          "component_kind": {
            "description": "The representation containing these observations.",
            "enum": [
              "document",
              "sheet",
              "media"
            ],
            "title": "Component Kind",
            "type": "string"
          },
          "components": {
            "description": "Supporting records grouped into this result, in query order, with their separate values and evidence. The row's component fields mirror the first record for display. Empty when no grouping was needed or on older results.",
            "items": {
              "$ref": "#/components/schemas/FilteredSearchComponent"
            },
            "title": "Components",
            "type": "array"
          },
          "content_matches": {
            "description": "Content criteria this row satisfied, with observed values and the source passages used to verify them.",
            "items": {
              "$ref": "#/components/schemas/ContentConditionMatch"
            },
            "title": "Content Matches",
            "type": "array"
          },
          "document_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The profiled document type of this component.",
            "title": "Document Type"
          },
          "entity_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The printed identifier of the matching entity within a register.",
            "title": "Entity Id"
          },
          "entry_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catalog entry identity, independent of query wording, filtering and rank. Supporting profile records share an established structural identity; incomplete identities can change on catalog rebuild. Null on legacy units.",
            "title": "Entry Id"
          },
          "page_end": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last source page containing the component.",
            "title": "Page End"
          },
          "page_start": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "First source page containing the component.",
            "title": "Page Start"
          },
          "source_file_id": {
            "description": "Stable identity of the uploaded source file.",
            "format": "uuid",
            "title": "Source File Id",
            "type": "string"
          },
          "source_path": {
            "description": "The uploaded file the result belongs to.",
            "title": "Source Path",
            "type": "string"
          },
          "source_row": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The native sheet row containing this entity's facts.",
            "title": "Source Row"
          },
          "subcategory": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The component's primary taxonomy subcategory.",
            "title": "Subcategory"
          },
          "summary": {
            "default": "",
            "description": "A description of the component's contents.",
            "title": "Summary",
            "type": "string"
          }
        },
        "required": [
          "component",
          "component_kind",
          "source_path",
          "source_file_id"
        ],
        "title": "FilteredSearchRow",
        "type": "object"
      },
      "FolderFileEntry": {
        "additionalProperties": false,
        "description": "One visible source file in a ``folder-metadata`` listing.\n\n``path`` is the uploaded source path — what the external audience addresses.\n``category`` and ``kind`` (the ingestion lane) are the triage facts: they say\nwhat a file is and which content tool family applies, without a\n``file-metadata`` call per file. ``derived_refs`` is the host's internal\ntwin, never serialized (``exclude=True``, same rule as\n:class:`~ndi_service.app.platform_api.contracts.Evidence`): the agent face\nexpands it into the derivative paths its readers accept.",
        "properties": {
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ledger document category, when classified.",
            "title": "Category"
          },
          "file_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The file's id, the `file_id` of `GET /files` — for the file routes (`/files/{file_id}`) without a separate listing. Absent on the agent face's derivative paths.",
            "title": "File Id"
          },
          "ingestion_status": {
            "$ref": "#/components/schemas/IngestionStatus",
            "description": "Where the file is in ingestion; only `ingested` files answer."
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ingestion lane (document / table / media), when known.",
            "title": "Kind"
          },
          "path": {
            "description": "Workspace-relative path of the uploaded file — pass it to file-metadata, qa-file or query-tables as is.",
            "title": "Path",
            "type": "string"
          },
          "size_bytes": {
            "description": "Byte size of the uploaded file.",
            "title": "Size Bytes",
            "type": "integer"
          },
          "uploaded_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When this file was first registered (ISO 8601).",
            "title": "Uploaded At"
          }
        },
        "required": [
          "path",
          "ingestion_status",
          "size_bytes"
        ],
        "title": "FolderFileEntry",
        "type": "object"
      },
      "FolderMetadataRequest": {
        "additionalProperties": false,
        "description": "Request body for ``folder-metadata``: describe one folder of the workspace.\n\nNon-recursive by default: the first call on a folder orients (its own files\nplus a summary per subfolder), and the caller descends or narrows from\nthere instead of receiving the whole subtree at once.\n\nA narrow (``category``, ``ingestion_status``, ``kind``, ``name_contains``)\n**implies recursion** unless ``recursive`` is sent explicitly: the counts\nthose names come from cover subtrees, so the follow-up call must scope the\nsame subtree. An explicit ``recursive=false`` alongside a narrow is honored.",
        "properties": {
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Omit to include every file. Use a name exactly as a previous response's `categories[].name` printed it, e.g. `minutes/meeting_minutes`.",
            "title": "Category"
          },
          "directory": {
            "default": "/",
            "description": "Folder to describe, relative to the workspace root: `/` (the default) is the root, `evidence/2025` a folder under it. Never prefix it with the workspace id.",
            "maxLength": 1024,
            "title": "Directory",
            "type": "string"
          },
          "ingestion_status": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IngestionStatus"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files in this ingestion status — e.g. `failed` to list what did not ingest."
          },
          "kind": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IngestionLane"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files of this kind: `document` (paged or prose), `table`, or `media`."
          },
          "name_contains": {
            "anyOf": [
              {
                "maxLength": 256,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files whose path contains this text, case-insensitively — how to find a file you know by name. `%` and `_` match literally.",
            "title": "Name Contains"
          },
          "page_size": {
            "default": 100,
            "description": "File entries per page. The counts always cover the whole scope.",
            "maximum": 500.0,
            "minimum": 1.0,
            "title": "Page Size",
            "type": "integer"
          },
          "recursive": {
            "default": false,
            "description": "Describe the folder's whole subtree instead of its own files only. A narrow implies true unless sent.",
            "title": "Recursive",
            "type": "boolean"
          },
          "start_after": {
            "anyOf": [
              {
                "maxLength": 1024,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Resume the file listing strictly after this path: the last `file_entries` path of the previous page.",
            "title": "Start After"
          }
        },
        "title": "FolderMetadataRequest",
        "type": "object"
      },
      "FolderMetadataResponse": {
        "additionalProperties": false,
        "description": "Response body for ``folder-metadata``.\n\nCounts are filtered by both the caller's access predicate and the requested\n``directory`` — the two compose as an intersection, so the view is neither\nwider than the access gate nor wider than the declared scope.\n\n``file_entries`` lists the visible source files the counts cover (same\nscope and recursion as the counts), path-sorted, one page at a time\n(``page_size``); ``files_truncated`` reports a cut page — resume with\n``start_after=<last path>``, or narrow. Source paths only, never ingestion\nderivatives.",
        "properties": {
          "categories": {
            "description": "File counts per category across the scope.",
            "items": {
              "$ref": "#/components/schemas/CategoryCount"
            },
            "title": "Categories",
            "type": "array"
          },
          "coverage": {
            "$ref": "#/components/schemas/Coverage",
            "description": "What the access gate withheld from these counts, as counts and label names only."
          },
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "directory": {
            "description": "The folder described, relative to the workspace root (`/` is the root).",
            "title": "Directory",
            "type": "string"
          },
          "file_entries": {
            "description": "Files in scope, sorted by path, one page at a time.",
            "items": {
              "$ref": "#/components/schemas/FolderFileEntry"
            },
            "title": "File Entries",
            "type": "array"
          },
          "files_truncated": {
            "description": "True when `file_entries` is one page of a longer listing; resume with `start_after`.",
            "title": "Files Truncated",
            "type": "boolean"
          },
          "hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only when a call matched nothing: unfiltered, the nearest existing folder and what it holds; filtered, how many files the folder holds and their categories.",
            "title": "Hint"
          },
          "ingestion_summary": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "File counts per ingestion status across the scope.",
            "propertyNames": {
              "$ref": "#/components/schemas/IngestionStatus"
            },
            "title": "Ingestion Summary",
            "type": "object"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The external operation job; absent for commands inside a search job.",
            "title": "Job Id"
          },
          "overall_files": {
            "description": "Files in scope that the caller can see: the folder, or its subtree when recursive.",
            "title": "Overall Files",
            "type": "integer"
          },
          "subdirectories": {
            "description": "The folder's immediate subfolders, each summarizing its subtree.",
            "items": {
              "$ref": "#/components/schemas/SubdirectorySummary"
            },
            "title": "Subdirectories",
            "type": "array"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "directory",
          "overall_files",
          "categories",
          "subdirectories",
          "ingestion_summary",
          "files_truncated",
          "file_entries",
          "coverage"
        ],
        "title": "FolderMetadataResponse",
        "type": "object"
      },
      "FolderMetadataResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "$ref": "#/components/schemas/FolderMetadataResponse",
            "description": "The operation response returned to the caller, retained with its job."
          },
          "result_type": {
            "const": "folder_metadata",
            "default": "folder_metadata",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "output"
        ],
        "title": "FolderMetadataResult",
        "type": "object"
      },
      "GenerateDomainRequest": {
        "additionalProperties": false,
        "description": "Ask the model for an unsaved taxonomy draft.\n\nNothing is persisted: the caller edits the draft, then posts it to\n``POST /v1/domains``. Optional ``display_name`` / ``slug`` seed the\nsuggested identity fields returned alongside the taxonomy. Exactly one\ninput is required: a written description, or a succeeded Parse job.",
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 4000,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What kinds of files belong in this domain — the classifier-facing brief.",
            "title": "Description"
          },
          "display_name": {
            "anyOf": [
              {
                "maxLength": 200,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional name hint used when suggesting a display name and slug.",
            "title": "Display Name"
          },
          "sheet_name": {
            "anyOf": [
              {
                "maxLength": 200,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workbook worksheet to extract. Required when the Parse result contains multiple sheets.",
            "title": "Sheet Name"
          },
          "slug": {
            "anyOf": [
              {
                "maxLength": 64,
                "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional slug hint. When omitted, the model derives one from the input.",
            "title": "Slug"
          },
          "source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseResultSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "Succeeded Parse job whose content contains the taxonomy to extract."
          }
        },
        "title": "GenerateDomainRequest",
        "type": "object"
      },
      "GenerateDomainResponse": {
        "additionalProperties": false,
        "description": "An unsaved draft ready for the authoring UI to edit and then create.",
        "properties": {
          "suggested_display_name": {
            "maxLength": 200,
            "minLength": 1,
            "title": "Suggested Display Name",
            "type": "string"
          },
          "suggested_slug": {
            "maxLength": 64,
            "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
            "title": "Suggested Slug",
            "type": "string"
          },
          "taxonomy": {
            "$ref": "#/components/schemas/Taxonomy-Output"
          },
          "validation": {
            "$ref": "#/components/schemas/DomainValidation",
            "description": "Publish-gate check on the normalized draft — always run so the UI knows it can create cleanly."
          }
        },
        "required": [
          "taxonomy",
          "suggested_slug",
          "suggested_display_name",
          "validation"
        ],
        "title": "GenerateDomainResponse",
        "type": "object"
      },
      "GranularRetention": {
        "description": "Retention for document operations — a **client** setting, not a request field.\n\nA data-handling guarantee a caller can accidentally opt out of on one\nendpoint is not a guarantee, so this is configured per client at onboarding\nand appears in no request body.",
        "enum": [
          "short",
          "zero_retention"
        ],
        "title": "GranularRetention",
        "type": "string"
      },
      "GrepMatch": {
        "additionalProperties": false,
        "description": "One matching line, placed where the file tools address it.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Public component of the line as file-metadata lists it and read-file accepts as component= (tab name, section); None when the file is the unit (an image, a recording, a raw upload).",
            "title": "Component"
          },
          "context_after": {
            "description": "The `after` lines below the match, clipped.",
            "items": {
              "type": "string"
            },
            "title": "Context After",
            "type": "array"
          },
          "context_before": {
            "description": "The `before` lines above the match (document text), clipped, top first.",
            "items": {
              "type": "string"
            },
            "title": "Context Before",
            "type": "array"
          },
          "file_id": {
            "description": "The uploaded file the line belongs to.",
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "kind": {
            "description": "What the component is: a document section, a spreadsheet tab, an image, a recording, or a raw upload.",
            "enum": [
              "section",
              "tab",
              "media",
              "image",
              "raw"
            ],
            "title": "Kind",
            "type": "string"
          },
          "line": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "1-based line number in the text read-file returns for path and component (for a single-component file, the same as reading the whole file); document text only. None on a pointer match: a spreadsheet tab (run-sql its sql_table for the answer), an image (its text or summary matched; ask-file reads it), a recording.",
            "title": "Line"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The source page the line sits on; None when the text has no pages or the match is a pointer.",
            "title": "Page"
          },
          "path": {
            "description": "Uploaded source path of the file.",
            "title": "Path",
            "type": "string"
          },
          "sql_table": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The run-sql table holding the component's rows (a spreadsheet tab, a document's long tables); None when it has none.",
            "title": "Sql Table"
          },
          "table": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GrepTable"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the line is a row of a table in document text: that table's lines, title and header row."
          },
          "text": {
            "description": "The matching line, clipped around its first match when it is long.",
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "file_id",
          "path",
          "component",
          "kind",
          "line",
          "page",
          "text"
        ],
        "title": "GrepMatch",
        "type": "object"
      },
      "GrepResponse": {
        "additionalProperties": false,
        "description": "Response of ``grep``.\n\n``files_unscanned`` counts the files that could hold a match but were not read because\n``max_matches`` or the scan budget ran out first — narrow with ``path_prefix`` to reach them.",
        "properties": {
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "files_matched": {
            "description": "How many of the scanned files had at least one matching line.",
            "title": "Files Matched",
            "type": "integer"
          },
          "files_scanned": {
            "description": "How many files were read and matched line by line.",
            "title": "Files Scanned",
            "type": "integer"
          },
          "files_unscanned": {
            "description": "Files that could match but were not read before the limits ran out.",
            "title": "Files Unscanned",
            "type": "integer"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The external operation job; absent for commands inside a search job.",
            "title": "Job Id"
          },
          "matches": {
            "description": "The matching lines, in path order then line order.",
            "items": {
              "$ref": "#/components/schemas/GrepMatch"
            },
            "title": "Matches",
            "type": "array"
          },
          "mode": {
            "description": "scan: every file in scope was read. index: the content index first narrowed the scope to the files holding the pattern's words, and those were read.",
            "enum": [
              "scan",
              "index"
            ],
            "title": "Mode",
            "type": "string"
          },
          "near_misses": {
            "description": "Only when nothing matched: scanned lines holding most of the pattern's words, best first — the document's own wording of what the pattern looked for.",
            "items": {
              "$ref": "#/components/schemas/GrepMatch"
            },
            "title": "Near Misses",
            "type": "array"
          },
          "notes": {
            "description": "How the pattern was read, when not as written.",
            "items": {
              "type": "string"
            },
            "title": "Notes",
            "type": "array"
          },
          "truncated": {
            "description": "True when max_matches or the scan budget cut the result short.",
            "title": "Truncated",
            "type": "boolean"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "matches",
          "files_matched",
          "files_scanned",
          "files_unscanned",
          "truncated",
          "mode"
        ],
        "title": "GrepResponse",
        "type": "object"
      },
      "GrepResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "$ref": "#/components/schemas/GrepResponse",
            "description": "The operation response returned to the caller, retained with its job."
          },
          "result_type": {
            "const": "grep",
            "default": "grep",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "output"
        ],
        "title": "GrepResult",
        "type": "object"
      },
      "GrepTable": {
        "additionalProperties": false,
        "description": "The table a matching line is a row of, so the row reads without another call.",
        "properties": {
          "first_line": {
            "description": "Line of the table's first row (its header), in read-file's line numbers.",
            "title": "First Line",
            "type": "integer"
          },
          "header": {
            "description": "The column names: the table's first row, or for an HTML table every header row joined per column with ' > ' (empty when it has none), clipped when very wide.",
            "title": "Header",
            "type": "string"
          },
          "last_line": {
            "description": "Line of the table's last row.",
            "title": "Last Line",
            "type": "integer"
          },
          "rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "For a table stored as one HTML line (PDF ingestion): how many data rows it has.",
            "title": "Rows"
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The text printed just above the table (its caption, units), clipped; None when there is none.",
            "title": "Title"
          }
        },
        "required": [
          "first_line",
          "last_line",
          "title",
          "header"
        ],
        "title": "GrepTable",
        "type": "object"
      },
      "GroundJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "ground",
            "default": "ground",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ndi_service__app__platform_api__results__GroundResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "GroundJob",
        "type": "object"
      },
      "GroundMatch": {
        "additionalProperties": false,
        "properties": {
          "confidence": {
            "anyOf": [
              {
                "maximum": 1.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "0-1 locator confidence when the grounding provider reports one. Independent of match_method: exact and normalized hits can carry a score too. Null only when the provider has no confidence for that match. This is not rank.",
            "title": "Confidence"
          },
          "cropped_image_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Crop URL when options.include_previews is true and the match has a visual region.",
            "title": "Cropped Image Url"
          },
          "location": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "json_pointer": "#/components/schemas/JsonPointer",
                    "page_region": "#/components/schemas/PageRegion",
                    "row_range": "#/components/schemas/RowRange",
                    "sheet_range": "#/components/schemas/SheetRange",
                    "table_region": "#/components/schemas/TableRegion",
                    "text_span": "#/components/schemas/TextSpan"
                  },
                  "propertyName": "kind"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/PageRegion"
                  },
                  {
                    "$ref": "#/components/schemas/SheetRange"
                  },
                  {
                    "$ref": "#/components/schemas/TextSpan"
                  },
                  {
                    "$ref": "#/components/schemas/RowRange"
                  },
                  {
                    "$ref": "#/components/schemas/TableRegion"
                  },
                  {
                    "$ref": "#/components/schemas/JsonPointer"
                  }
                ]
              },
              {
                "discriminator": {
                  "mapping": {
                    "audio_range": "#/components/schemas/AudioRange",
                    "json_pointer": "#/components/schemas/JsonPointer",
                    "jsonl_record": "#/components/schemas/JsonlRecord",
                    "row_range": "#/components/schemas/RowRange",
                    "spreadsheet_range": "#/components/schemas/SpreadsheetRange",
                    "text_range": "#/components/schemas/TextRange",
                    "visual_region": "#/components/schemas/VisualRegion"
                  },
                  "propertyName": "kind"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/TextRange"
                  },
                  {
                    "$ref": "#/components/schemas/VisualRegion"
                  },
                  {
                    "$ref": "#/components/schemas/SpreadsheetRange"
                  },
                  {
                    "$ref": "#/components/schemas/JsonlRecord"
                  },
                  {
                    "$ref": "#/components/schemas/JsonPointer"
                  },
                  {
                    "$ref": "#/components/schemas/AudioRange"
                  },
                  {
                    "$ref": "#/components/schemas/RowRange"
                  }
                ]
              }
            ],
            "description": "Where the quote was found. Kind follows the source: page_region for PDF or image polygons, text_span for character offsets — into the derived text for most sources, but into the uploaded file itself for HTML and email, so tags and headers are counted — sheet_range for a workbook tab and A1, json_pointer for JSON, jsonl_record for a JSONL line, row_range for table rows, or audio_range for media timestamps.",
            "title": "Location"
          },
          "match_method": {
            "description": "How this hit was accepted: exact is a character-for-character copy of the target, normalized ignores case and punctuation, semantic is a meaning-similar or visual hit.",
            "enum": [
              "exact",
              "normalized",
              "semantic"
            ],
            "title": "Match Method",
            "type": "string"
          },
          "matched_text": {
            "description": "The string actually found at location. Can differ from the request target text when match_method is normalized or semantic.",
            "title": "Matched Text",
            "type": "string"
          },
          "rank": {
            "description": "1-based position in this target's matches after the matcher has sorted hits best-first. 1 is the primary location; later ranks are other occurrences or weaker hits. On an HTML source, a hint ranks the visible occurrence nearest that nearby text first; without a hint, rank 1 is the first visible occurrence. Rank restarts at 1 on every target. The list is capped by options.max_matches. Not a score — use match_method and confidence.",
            "minimum": 1.0,
            "title": "Rank",
            "type": "integer"
          },
          "word_anchor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WordAnchor"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unique literal occurrence in the original DOCX/DOCM paragraph text, when available."
          }
        },
        "required": [
          "rank",
          "matched_text",
          "match_method",
          "location"
        ],
        "title": "GroundMatch",
        "type": "object"
      },
      "GroundOptions-Output": {
        "additionalProperties": false,
        "properties": {
          "include_previews": {
            "default": false,
            "description": "When true, matches include cropped_image_url for visual regions. Fetch with the same API key.",
            "title": "Include Previews",
            "type": "boolean"
          },
          "max_matches": {
            "default": 10,
            "description": "Maximum matches to return per target, ranked best-first. An HTML source is capped the same way, but only visible rendered text is matched: text hidden by its own style attribute, a hidden or aria-hidden attribute, or an unopened <dialog> is never returned. Hiding that comes from a stylesheet or a media query is not evaluated. A hint ranks the visible occurrence nearest that nearby text first; without a hint, rank 1 is the first visible occurrence.",
            "maximum": 50.0,
            "minimum": 1.0,
            "title": "Max Matches",
            "type": "integer"
          },
          "minimum_semantic_score": {
            "anyOf": [
              {
                "maximum": 1.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Deprecated minimum score for semantic and model-scored matches. The exact-match PDF, Word and PowerPoint runtime ignores it: a semantic pick there is kept only when the model rates it above no answer. Exact and normalized matches are unaffected.",
            "title": "Minimum Semantic Score"
          },
          "require_visual_region": {
            "default": false,
            "description": "When true, only matches that have a visual region are kept. Not supported by the current runtime.",
            "title": "Require Visual Region",
            "type": "boolean"
          },
          "use_word_level_grounding": {
            "default": false,
            "description": "Experimental. Match targets against word-level OCR bboxes. PDF sources only. Targets shorter than 2 normalized characters return status failed with error needle_too_short.",
            "title": "Use Word Level Grounding",
            "type": "boolean"
          }
        },
        "title": "GroundOptions",
        "type": "object"
      },
      "GroundParseSettings": {
        "additionalProperties": false,
        "description": "Settings for the shared Parse Ground reads. Ground has no high mode: it bills per target, not per page.",
        "properties": {
          "diagrams": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseDiagramsOptions"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether flowchart-like figures are rewritten as Mermaid fences, as diagrams on Parse. Defaults to omit."
          },
          "figures": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettingsFigures"
              },
              {
                "type": "null"
              }
            ],
            "description": "How figure regions are kept in the Parse this operation reads. Omit to keep figures. Only figures.mode omit changes the Parse."
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive pages to read, as page_ranges on Parse. On an operation with its own page_ranges the two must agree. With a parse_result source it keeps only those pages of the reused Parse.",
            "title": "Page Ranges"
          },
          "parse_mode": {
            "anyOf": [
              {
                "enum": [
                  "low",
                  "medium"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Parsing effort for the Parse Ground reads: low (the default) or medium. high is not accepted.",
            "title": "Parse Mode"
          },
          "spreadsheet": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSpreadsheetOptions"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workbook controls, as spreadsheet on Parse. Applied to spreadsheet sources only."
          }
        },
        "title": "GroundParseSettings",
        "type": "object"
      },
      "GroundRequest": {
        "additionalProperties": false,
        "description": "Body for canonical ``POST /v1/ground``.\n\n``targets`` is the canonical p0 locator contract: caller-supplied text to\nresolve back to source locations.\n``claims`` remains as a legacy compatibility shape for existing callers.",
        "properties": {
          "claims": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/Claim"
                },
                "maxItems": 30,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy locator shape. Prefer targets. Exactly one of claims or targets must be set.",
            "title": "Claims"
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "options": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__document_operations__schemas__GroundOptions",
            "description": "Match caps, semantic score floor, and whether to mint crop preview URLs."
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GroundParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the shared Parse Ground reads, using the same fields as Parse. Omit to use the default Parse. parse_mode high is not accepted on Ground. Only PDF, image, and Word sources on the native_1 provider read that Parse. Elsewhere the settings are not applied and the result's warnings say so. page_ranges keeps only matches on those pages."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "source": {
            "description": "The document to search: a fresh upload, an HTTPS URL, a workspace file, or a prior parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          },
          "targets": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/GroundTarget"
                },
                "maxItems": 30,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quoted strings to locate, up to 30. Exactly one of claims or targets must be set.",
            "title": "Targets"
          }
        },
        "required": [
          "source"
        ],
        "title": "GroundRequest",
        "type": "object"
      },
      "GroundRequestEcho": {
        "additionalProperties": false,
        "description": "A stored ``ground`` request, read back.",
        "properties": {
          "claims": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/Claim"
                },
                "maxItems": 30,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy locator shape. Prefer targets. Exactly one of claims or targets must be set.",
            "title": "Claims"
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "options": {
            "$ref": "#/components/schemas/GroundOptions-Output",
            "description": "Match caps, semantic score floor, and whether to mint crop preview URLs."
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GroundParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the shared Parse Ground reads, using the same fields as Parse. Omit to use the default Parse. parse_mode high is not accepted on Ground. Only PDF, image, and Word sources on the native_1 provider read that Parse. Elsewhere the settings are not applied and the result's warnings say so. page_ranges keeps only matches on those pages."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "request_type": {
            "const": "ground",
            "default": "ground",
            "title": "Request Type",
            "type": "string"
          },
          "source": {
            "description": "The document to search: a fresh upload, an HTTPS URL, a workspace file, or a prior parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          },
          "targets": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/GroundTarget"
                },
                "maxItems": 30,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quoted strings to locate, up to 30. Exactly one of claims or targets must be set.",
            "title": "Targets"
          }
        },
        "required": [
          "source"
        ],
        "title": "GroundRequestEcho",
        "type": "object"
      },
      "GroundTarget": {
        "additionalProperties": false,
        "description": "One piece of text to locate in the source document.\n\n``hint`` is nearby free-text context. ``page_hints`` carries 1-based pages\nto prioritize during visual/document search. ``sheet`` names the\nspreadsheet tab to search when the source is a workbook — the same name\nsearch and tool citations publish as ``component`` — so a 30-sheet\nworkbook is not searched whole. Ignored for non-spreadsheet sources.",
        "properties": {
          "hint": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nearby free-text context that helps disambiguate a repeated quote.",
            "title": "Hint"
          },
          "id": {
            "description": "Caller-defined id echoed on the matching result target.",
            "title": "Id",
            "type": "string"
          },
          "page_hints": {
            "anyOf": [
              {
                "items": {
                  "minimum": 1.0,
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional 1-based pages to search first.",
            "title": "Page Hints"
          },
          "semantic": {
            "default": false,
            "description": "When true, text is a description of what to find, not a quote. On deployments that ground PDF, Word and PowerPoint sources with the exact-match runtime, the description picks up to max_matches sentences, table cells, lines, blocks, sections (a heading with its text) or table rows that answer it, best first, and each comes back as an exact match with match_method semantic. hint steers the pick. A target whose answer is not in the source comes back not found. On those deployments, if the picking model is unavailable, the target fails with error native_2_semantic_unavailable. Use false for exact text matching.",
            "title": "Semantic",
            "type": "boolean"
          },
          "sheet": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workbook tab to search. Ignored for non-spreadsheet sources.",
            "title": "Sheet"
          },
          "text": {
            "description": "Quoted string to locate in the source.",
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "id",
          "text"
        ],
        "title": "GroundTarget",
        "type": "object"
      },
      "GroundTargetResult": {
        "additionalProperties": false,
        "properties": {
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Machine-readable reason when status is failed, for example needle_too_short. Null otherwise.",
            "title": "Error"
          },
          "id": {
            "description": "Caller-defined id from the request targets list. Join request to result on this, not on quote text.",
            "title": "Id",
            "type": "string"
          },
          "matches": {
            "description": "Locations for this target, sorted best-first and numbered by rank. Empty when not found.",
            "items": {
              "$ref": "#/components/schemas/GroundMatch"
            },
            "title": "Matches",
            "type": "array"
          },
          "status": {
            "description": "Per-target outcome: found has at least one location, not_found means the quote is not in the document (the job still succeeded), failed is a target-level error.",
            "enum": [
              "found",
              "not_found",
              "failed"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id",
          "status"
        ],
        "title": "GroundTargetResult",
        "type": "object"
      },
      "HybridSearchResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "$ref": "#/components/schemas/SearchResponse",
            "description": "The operation response returned to the caller, retained with its job."
          },
          "result_type": {
            "const": "hybrid_search",
            "default": "hybrid_search",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "output"
        ],
        "title": "HybridSearchResult",
        "type": "object"
      },
      "IngestRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /v1/workspaces/{workspace_id}/ingestions``.\n\n``selection`` is the discriminated union that says *what* to process:\n\n* ``{\"type\": \"file_ids\", \"file_ids\": [...]}`` — one file or an explicit\n  batch (up to MAX_INGESTION_BATCH files).\n* ``{\"type\": \"path_prefix\", \"path_prefix\": \"reports/\"}`` — a folder;\n  ``\"\"`` or ``\"/\"`` means the whole workspace.  Set ``stale_only`` to\n  re-ingest only files whose observed hash diverged from the ingested hash\n  since the last run — the routine reconciliation-driven case.\n\nThe ingestion lane (PDF, spreadsheet, audio, etc.) is chosen per file from\nthe file type inside the run.  A caller that had to name a lane would be\nmaintaining the platform's routing table; the union keeps that responsibility\nwhere it belongs.",
        "properties": {
          "reingest_unchanged": {
            "default": false,
            "title": "Reingest Unchanged",
            "type": "boolean"
          },
          "selection": {
            "discriminator": {
              "mapping": {
                "file_ids": "#/components/schemas/FileIdsSelection",
                "path_prefix": "#/components/schemas/PathPrefixSelection"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/FileIdsSelection"
              },
              {
                "$ref": "#/components/schemas/PathPrefixSelection"
              }
            ],
            "title": "Selection"
          }
        },
        "required": [
          "selection"
        ],
        "title": "IngestRequest",
        "type": "object"
      },
      "IngestedFileOutcome": {
        "additionalProperties": false,
        "description": "Per-file, because one corrupt file in a folder of 400 must not fail the run.",
        "properties": {
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ]
          },
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "lane": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lane"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "status": {
            "enum": [
              "ingested",
              "skipped_unchanged",
              "skipped_empty",
              "failed"
            ],
            "title": "Status",
            "type": "string"
          },
          "units": {
            "default": 0,
            "title": "Units",
            "type": "integer"
          }
        },
        "required": [
          "file_id",
          "path",
          "status"
        ],
        "title": "IngestedFileOutcome",
        "type": "object"
      },
      "IngestionJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "ingestion",
            "default": "ingestion",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IngestionResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "IngestionJob",
        "type": "object"
      },
      "IngestionLane": {
        "description": "The processing lane a file routes through — exactly one per file.\n\n``DOCUMENT`` covers everything the categorize pipeline can split into\nlogical documents (PDF, Office, Visio diagrams, images, text, markdown, HTML, email);\n``TABLE`` covers spreadsheets and CSV; ``MEDIA`` covers audio and video,\nwhich become one speaker-attributed timeline plus sampled frames;\n``JSON`` preserves arbitrary nested structure and may add a table\nprojection for a top-level record array.",
        "enum": [
          "document",
          "table",
          "media",
          "json"
        ],
        "title": "IngestionLane",
        "type": "string"
      },
      "IngestionResult": {
        "additionalProperties": false,
        "properties": {
          "files_empty": {
            "default": 0,
            "description": "Files skipped because a valid Parquet input contained zero rows.",
            "title": "Files Empty",
            "type": "integer"
          },
          "files_failed": {
            "title": "Files Failed",
            "type": "integer"
          },
          "files_ingested": {
            "title": "Files Ingested",
            "type": "integer"
          },
          "files_skipped": {
            "title": "Files Skipped",
            "type": "integer"
          },
          "kg_build_job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The knowledge-graph build this ingestion chained, when the workspace auto-builds. Poll it to know when the graph covers these files; null means no build was chained (auto-build off, or a pending build already covers them).",
            "title": "Kg Build Job Id"
          },
          "ledger_understanding_job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The ledger-understanding run this ingestion chained. Null when none was: the workspace holds no journal-line table, an artefact for this exact package already exists, one is already queued, or the workspace turned chaining off.",
            "title": "Ledger Understanding Job Id"
          },
          "outcomes": {
            "items": {
              "$ref": "#/components/schemas/IngestedFileOutcome"
            },
            "title": "Outcomes",
            "type": "array"
          },
          "result_type": {
            "const": "ingestion",
            "default": "ingestion",
            "title": "Result Type",
            "type": "string"
          },
          "units_total": {
            "title": "Units Total",
            "type": "integer"
          }
        },
        "required": [
          "outcomes",
          "files_ingested",
          "files_skipped",
          "files_failed",
          "units_total"
        ],
        "title": "IngestionResult",
        "type": "object"
      },
      "IngestionStatus": {
        "description": "The only thing that says whether a file is searchable.\n\n``expired`` cannot be derived from the hash pair: retention clears\n``ingested_hash``, so an aged-out file and a never-ingested file look\nidentical. They call for different customer actions, so the status carries\nthe distinction the hashes cannot.",
        "enum": [
          "discovered",
          "queued",
          "ingesting",
          "ingested",
          "stale",
          "expired",
          "failed",
          "not_required"
        ],
        "title": "IngestionStatus",
        "type": "string"
      },
      "InitialFilteredSearch": {
        "additionalProperties": false,
        "description": "Start a filtered search: a natural-language filter/rank/count request.",
        "properties": {
          "allow_clarification": {
            "default": false,
            "description": "Let the run finish with ONE clarifying question instead of a result, when the request is genuinely ambiguous and the ambiguity materially changes the result. The rejected result carries the question in `clarification` (no rows, no applied_query, exhaustive false); filtered search keeps no session, so answer it by issuing a new initial query. Off — the default — means the run always executes.",
            "title": "Allow Clarification",
            "type": "boolean"
          },
          "context": {
            "anyOf": [
              {
                "maxLength": 20000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Context"
          },
          "path_prefix": {
            "anyOf": [
              {
                "maxLength": 1024,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Narrow the run to a folder subtree. It intersects with the access filter, never overrides it.",
            "title": "Path Prefix"
          },
          "paths": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 1024,
                  "minLength": 1,
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Narrow the run to exactly these uploaded files: only catalog entries extracted from them can match, and the agent's searches and reads see only them. Each entry names an uploaded source file (never a folder — scope folders with path_prefix; the two add up, so the catalog covers the folder's files plus these). No limit on how many. Unknown or inaccessible paths are refused up front.",
            "title": "Paths"
          },
          "query": {
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "result_unit": {
            "anyOf": [
              {
                "enum": [
                  "source",
                  "component",
                  "entity"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "deprecated": true,
            "description": "Legacy grouping override. Omit to return catalog entries with their established identities. Supporting sections retain their separate evidence. Explicit legacy values keep their original grouping, counting and pagination semantics.",
            "title": "Result Unit"
          },
          "type": {
            "const": "query",
            "default": "query",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "query"
        ],
        "title": "InitialFilteredSearch",
        "type": "object"
      },
      "IntegrityFindingWire": {
        "additionalProperties": false,
        "description": "One thing the integrity battery established about the population.",
        "properties": {
          "amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The money figure behind the count, at the ledger's own scale.",
            "title": "Amount"
          },
          "check": {
            "description": "Which question of the integrity battery this finding answers, by its check id.",
            "title": "Check",
            "type": "string"
          },
          "count": {
            "description": "Rows, journals or values the check found, depending on what it asks.",
            "title": "Count",
            "type": "integer"
          },
          "message": {
            "description": "One sentence stating the finding in this package's own column names.",
            "title": "Message",
            "type": "string"
          },
          "sample_keys": {
            "description": "A bounded, ascending sample of the offending keys, so a reader can go and look at them.",
            "items": {
              "type": "string"
            },
            "title": "Sample Keys",
            "type": "array"
          },
          "scope": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The slice this figure is for, such as one entity or one column. Null is the whole file.",
            "title": "Scope"
          },
          "severity": {
            "description": "How to read it: informational, a warning to weigh, or a structural absence that blocks.",
            "enum": [
              "info",
              "warning",
              "blocking"
            ],
            "title": "Severity",
            "type": "string"
          },
          "table": {
            "description": "The table the finding is about.",
            "title": "Table",
            "type": "string"
          }
        },
        "required": [
          "check",
          "severity",
          "table",
          "count",
          "sample_keys",
          "message"
        ],
        "title": "IntegrityFindingWire",
        "type": "object"
      },
      "IntegrityReportWire": {
        "additionalProperties": false,
        "description": "Whether this population is fit to test, and what could not be asked.",
        "properties": {
          "blocking": {
            "description": "Whether the package is missing something structural — a balanceable amount, a date, or an account — which is the only condition that stops the stage going further.",
            "title": "Blocking",
            "type": "boolean"
          },
          "executions": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/CheckExecutionWire"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Per-statement outcomes; null on legacy readings.",
            "title": "Executions"
          },
          "findings": {
            "description": "Everything the battery established, in plan order.",
            "items": {
              "$ref": "#/components/schemas/IntegrityFindingWire"
            },
            "title": "Findings",
            "type": "array"
          },
          "skipped": {
            "description": "Checks that did not run. Reported rather than dropped, because an untested condition and a clean one are different answers.",
            "items": {
              "$ref": "#/components/schemas/SkippedCheckWire"
            },
            "title": "Skipped",
            "type": "array"
          }
        },
        "required": [
          "findings",
          "skipped",
          "blocking"
        ],
        "title": "IntegrityReportWire",
        "type": "object"
      },
      "IntelligentSearchJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "intelligent_search",
            "default": "intelligent_search",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IntelligentSearchResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "IntelligentSearchJob",
        "type": "object"
      },
      "IntelligentSearchResult": {
        "additionalProperties": false,
        "properties": {
          "answer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A direct answer to the query, grounded in the evidences. Always present on a newly finalized run that answered; null when the run rejected the query with a `clarification`, and on results stored before answers became unconditional (the evidence-only mode).",
            "title": "Answer"
          },
          "cache": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AnswerCacheInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when this answer was re-served from the workspace's answer cache instead of derived by this run, with the provenance of the run that did derive it. Null on every run that computed its own answer."
          },
          "candidates_seen": {
            "default": 0,
            "title": "Candidates Seen",
            "type": "integer"
          },
          "claims": {
            "description": "Calculated answer values bound to recorded executions.",
            "items": {
              "$ref": "#/components/schemas/DeepSearchVerifiedClaim"
            },
            "title": "Claims",
            "type": "array"
          },
          "clarification": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Non-null exactly when the run rejected the query as genuinely ambiguous instead of answering — only possible when the request set `allow_clarification`: one direct question back to the caller, with `answer` and `reasoning` null and `evidences` empty. Answer it by re-asking in the same thread via the result's `session_id`.",
            "title": "Clarification"
          },
          "command_receipts": {
            "description": "Successful shell calculations cited by this answer.",
            "items": {
              "$ref": "#/components/schemas/CommandReceipt"
            },
            "title": "Command Receipts",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The agent's self-graded confidence in the answer — how well the evidence it retrieved supports it, on the shared six-level scale (certain / very_high / high / medium / low / speculative). Null on runs rejected with a `clarification` and on results stored before the field existed."
          },
          "coverage": {
            "$ref": "#/components/schemas/Coverage"
          },
          "evidences": {
            "description": "The evidence the agent found for the query, in order of importance.",
            "items": {
              "$ref": "#/components/schemas/SearchEvidence"
            },
            "title": "Evidences",
            "type": "array"
          },
          "exhausted": {
            "default": false,
            "description": "Budget hit before the loop was satisfied. A successful response, not a failure. When the agent authored no answer or reasoning, reasoning carries an actionable briefing and answer stays null so presentation does not treat the briefing as an answer.",
            "title": "Exhausted",
            "type": "boolean"
          },
          "grounding_job_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ground jobs planned for this search's evidences. Empty when postprocessing is disabled for this caller by deployment policy, explicitly disabled for the run, or no evidence is groundable. Absent on older results. When empty or absent, callers may POST /v1/ground explicitly to locate quotes.",
            "title": "Grounding Job Ids"
          },
          "reasoning": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The agent's account of how the pieces of evidence chain together to address the query, including any assumption it made in reading the query.",
            "title": "Reasoning"
          },
          "result_type": {
            "const": "intelligent_search",
            "default": "intelligent_search",
            "title": "Result Type",
            "type": "string"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The conversation this run belongs to. Send it back as the request's `session_id` to ask a follow-up in the same thread. Null only on results finalized before sessions existed.",
            "title": "Session Id"
          },
          "sql_receipts": {
            "description": "SQL executions supporting calculated answer claims.",
            "items": {
              "$ref": "#/components/schemas/SqlReceipt"
            },
            "title": "Sql Receipts",
            "type": "array"
          },
          "steps_used": {
            "default": 0,
            "title": "Steps Used",
            "type": "integer"
          },
          "structured_answer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JsonValue"
              },
              {
                "type": "null"
              }
            ],
            "description": "`answer` parsed as JSON, set only when the request carried `output_schema` and the answer validates against it; a field the source does not state is null whatever type the schema gives it. Null on every run without a schema, and on a run whose answer still missed the schema after its corrections, where `answer` holds the text as written."
          },
          "tool_calls": {
            "items": {
              "$ref": "#/components/schemas/ToolCallTrace"
            },
            "title": "Tool Calls",
            "type": "array"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SearchLlmUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What this run spent on LLM calls. Present only when the request asked for it; null means nothing was measured, not that nothing was spent."
          }
        },
        "title": "IntelligentSearchResult",
        "type": "object"
      },
      "JeTestingBody": {
        "additionalProperties": false,
        "description": "Body for ``POST /workspaces/{workspace_id}/je-testing``.",
        "properties": {
          "allow_clarification": {
            "default": false,
            "description": "Let the agent stop and ask instead of answering, when the test needs something the data cannot tell it (a threshold, the period or entity in scope, the client's definition of a term) or the work turns up a material ambiguity the request does not settle. The result then carries the questions in `clarification_questions` (and as text in `clarification`), with `answer` null; answer them in the same thread via the result's `session_id`, with `clarification_answers` or a follow-up query. Off, the default, means the agent always answers, naming the assumptions it made.",
            "title": "Allow Clarification",
            "type": "boolean"
          },
          "clarification_answers": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ClarificationAnswer"
                },
                "maxItems": 2,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Answers to the clarifying questions this thread's last turn asked (its result's `clarification_questions`): one entry per question, in order. Send them with that turn's `session_id` and its `query`; the agent then answers that query with the answers applied, and sees which answer belongs to which of its questions. Any other follow-up query in the thread works too — this field is the structured way to answer. Cannot be combined with `allow_clarification`: a run answering questions does not ask again.",
            "title": "Clarification Answers"
          },
          "context": {
            "anyOf": [
              {
                "maxLength": 20000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Free-form background for the model — the engagement, the entity, what the caller already knows. It informs the answer; it does not widen or narrow which files the caller may see.",
            "title": "Context"
          },
          "effort": {
            "anyOf": [
              {
                "enum": [
                  "high",
                  "medium",
                  "low"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "deprecated": true,
            "description": "Deprecated and ignored: the service resolves the run's configuration itself. Accepted so clients released before the effort levels were retired keep working; omit it.",
            "title": "Effort"
          },
          "path_prefix": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Put every uploaded file under one folder subtree, workspace-relative, in the run's scope; `paths`, where the body takes it, adds more files. Omit both for the whole workspace.",
            "title": "Path Prefix"
          },
          "paths": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 1024,
                  "minLength": 1,
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Scope the run to exactly these uploaded files — the ledger package to test. Every tool the agent runs (listings, reads, SQL) sees only these files and the content ingested from them. Each entry names an uploaded source file, never a folder; scope folders with path_prefix, which adds its files to these. No limit on how many. Unknown or inaccessible paths are refused up front. Omit to test the whole workspace: the agent then orients over every queryable file the caller can see and finds the ledger package itself, exactly as deep-search does when unscoped.",
            "title": "Paths"
          },
          "query": {
            "description": "What to answer, in the caller's own words. Stripped before its length is checked; a blank query is refused rather than run.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "reasoning_effort": {
            "anyOf": [
              {
                "enum": [
                  "none",
                  "minimal",
                  "low",
                  "medium",
                  "high"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "default": "low",
            "description": "Thinking budget for the testing agent; changing it does not change the engine. Null keeps the catalogue's per-model prescription. The console's Effort pill sends 'low' (default) or 'medium'.",
            "title": "Reasoning Effort"
          },
          "selection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Confirmed ledger source selection; mutually exclusive with path selectors.",
            "title": "Selection Id"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Continue a prior je-testing conversation: the id echoed on an earlier result's `session_id`. The agent resumes with that thread's full context — its orientation and its receipted statements — and treats this request as the follow-up. Omit to start a new thread. Only the API key that started the thread may continue it; a thread whose turn is still running returns 409 session_busy.",
            "title": "Session Id"
          }
        },
        "required": [
          "query"
        ],
        "title": "JeTestingBody",
        "type": "object"
      },
      "JeTestingJob": {
        "additionalProperties": false,
        "description": "The je-testing route's response shape.\n\nOne kind, one result: the agent engine answers on ``je_testing``. The\npipeline engine behind ``je-testing-v2`` answers on the same ``JetResult``\nunder its own kind, but that route is unpublished, so this shape names only\nthe kind a caller of the published route can receive.",
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "je_testing",
            "default": "je_testing",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JetResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "JeTestingJob",
        "type": "object"
      },
      "JetAgentUsage": {
        "additionalProperties": false,
        "description": "Completed root-agent model requests by session phase.\n\nThis is intentionally separate from :class:`SearchLlmUsage`: that ledger\ncovers every nested LLM call and token, while this block explains the agent\nprocedure itself. Provider transport attempts are not exposed by the model\nboundary reliably and are therefore not guessed here.",
        "properties": {
          "compaction_requests": {
            "description": "Completed model requests used to summarize compacted history.",
            "minimum": 0.0,
            "title": "Compaction Requests",
            "type": "integer"
          },
          "execution_requests": {
            "description": "Completed model requests in normal execution cycles.",
            "minimum": 0.0,
            "title": "Execution Requests",
            "type": "integer"
          },
          "finalization_requests": {
            "description": "Completed requests in the tool-less recovery finalizer.",
            "minimum": 0.0,
            "title": "Finalization Requests",
            "type": "integer"
          },
          "total_requests": {
            "description": "Sum of execution, compaction, and finalization requests.",
            "minimum": 0.0,
            "title": "Total Requests",
            "type": "integer"
          }
        },
        "required": [
          "execution_requests",
          "compaction_requests",
          "finalization_requests",
          "total_requests"
        ],
        "title": "JetAgentUsage",
        "type": "object"
      },
      "JetBreakdown": {
        "additionalProperties": false,
        "description": "The tabular result behind one figure, attached by the server.\n\nWhat a caller asking \"by FSLI and month\" or \"top 10 preparers\" wanted, in the\nshape the question implies. The rows are NOT model-authored and never were:\nthey are the cited receipt's own result, stringified and capped here, attached\nat finalize from :class:`SqlReceipt` rows the run already published. That is\nthe whole design — a figure's table costs the model no output tokens and\ncannot carry a cell no statement returned — and it is why there is no\nreshaping either: the receipt's shape IS the breakdown, so a matrix the SQL\nnever grouped by month is a wrong statement rather than a rendering problem.\n\n``result_id`` names the receipt the rows came from, which is always one of the\nfigure's own citations — either on ``result_ids`` or its ``exception_listing_result_id``,\nthe two id sets the console makes openable — so the breakdown is a convenience\nover the payload's own working, never a second source of truth, and a reader who\nwants the statement, the whole bounded result or its row provenance follows that\nid. (When the model names a listing it did not also list in ``receipt_ids``, that\nid reaches the figure through ``exception_listing_result_id`` rather than\n``result_ids``; both render as receipt buttons, so the table stays one click away\neither way.)",
        "properties": {
          "columns": {
            "description": "Column names, in the statement's own result order.",
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "result_id": {
            "description": "`sql_receipts[].result_id` of the statement these rows are.",
            "title": "Result Id",
            "type": "string"
          },
          "rows": {
            "description": "Rows in receipt order, cells as text so a decimal, a date and a NULL all survive the wire. At most 200; a longer result sets `truncated` and stays whole on its receipt.",
            "items": {
              "items": {
                "type": "string"
              },
              "type": "array"
            },
            "title": "Rows",
            "type": "array"
          },
          "truncated": {
            "default": false,
            "description": "Whether rows were cut — either by this table's own cap or already on the receipt it came from. A capped breakdown is never read as the complete listing.",
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "required": [
          "result_id"
        ],
        "title": "JetBreakdown",
        "type": "object"
      },
      "JetCriterionOutcome": {
        "additionalProperties": false,
        "description": "The final disposition of one requested test.",
        "properties": {
          "blocker": {
            "anyOf": [
              {
                "enum": [
                  "binding_unresolved",
                  "measurement_failed",
                  "missing_finding",
                  "population_incomplete",
                  "context_exhausted",
                  "missing_business_parameter",
                  "methodology_unresolved",
                  "finding_unverified"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why an incomplete test did not finish, including reasons newer than the three `incomplete_reason` keeps to. Null for performed and cannot-be-performed tests.",
            "title": "Blocker"
          },
          "criterion_id": {
            "description": "Stable short id for this requested test. Its TestSpec and published figure use the same id.",
            "minLength": 1,
            "title": "Criterion Id",
            "type": "string"
          },
          "description": {
            "description": "The requested test in the caller's terms, without an invented conclusion.",
            "minLength": 1,
            "title": "Description",
            "type": "string"
          },
          "incomplete_reason": {
            "anyOf": [
              {
                "enum": [
                  "binding_unresolved",
                  "measurement_failed",
                  "missing_finding"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "`blocker` in the three values older SDKs accept: `population_incomplete` and `finding_unverified` read as `measurement_failed`, and every other newer blocker as `missing_finding`. Read `blocker` for the full reason.",
            "title": "Incomplete Reason"
          },
          "missing_parameters": {
            "description": "Policy inputs this test was missing. Set only when `blocker` is `missing_business_parameter` or `methodology_unresolved`; empty otherwise.",
            "items": {
              "enum": [
                "close_cutoff",
                "balance_tolerance",
                "selected_user",
                "authority_limit",
                "methodology",
                "required_fields"
              ],
              "type": "string"
            },
            "title": "Missing Parameters",
            "type": "array"
          },
          "spec_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The committed TestSpec id and matching `figures[].spec_id`. Null when setup never reached a spec.",
            "title": "Spec Id"
          },
          "status": {
            "description": "Whether the test produced a finding, proved it could not be performed, or remained incomplete.",
            "enum": [
              "performed",
              "cannot_be_performed",
              "incomplete"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "criterion_id",
          "description",
          "status"
        ],
        "title": "JetCriterionOutcome",
        "type": "object"
      },
      "JetFigure": {
        "additionalProperties": false,
        "description": "One criterion the run tested, and the statements its figures come from.\n\nThe answer's structure on the wire. ``JetResult.answer`` is prose a person\nreads; this is the same content a reviewer can *check*: the definition the\nfigure was computed under, the population it was computed over, the spec that\npinned both, and the ``sql_receipts`` entries the figures are readable out of.\n\nEvery ``result_id`` here names a receipt on the same result, so a reader\nfollows a figure to its statement and its rows without leaving the payload.\n``exception_listing_result_id`` is the one worth opening: an unfiltered count\ngrounds correctly but points at every row, while an exception listing points\nat the rows that failed.",
        "properties": {
          "band_group": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when this figure is one band of a family that partitions a population — the same name on every band of the family, whose counts sum to that population.",
            "title": "Band Group"
          },
          "breakdown": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JetBreakdown"
              },
              {
                "type": "null"
              }
            ],
            "description": "The tabular result behind this figure, attached by the server from the receipt it cites — the exception listing where there is one, otherwise the single cited statement that returned more than one row. Null when no cited statement holds a table, and on a criterion that could not be performed."
          },
          "cannot_be_performed": {
            "default": false,
            "description": "The workspace does not hold the material this criterion needs. `result_ids` then name the probes that establish the absence rather than the figures.",
            "title": "Cannot Be Performed",
            "type": "boolean"
          },
          "count": {
            "description": "Members of the population that met the criterion.",
            "minimum": 0.0,
            "title": "Count",
            "type": "integer"
          },
          "criterion": {
            "description": "What was tested, in the caller's terms.",
            "title": "Criterion",
            "type": "string"
          },
          "definition": {
            "description": "The definition it was tested under: which column and values encoded the term, which clock, which basis, which threshold and where it came from.",
            "title": "Definition",
            "type": "string"
          },
          "exception_listing_result_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The receipt that lists the exceptions themselves, when one was produced.",
            "title": "Exception Listing Result Id"
          },
          "population": {
            "description": "The denominator — rows at this test's grain that the criterion ran over.",
            "minimum": 0.0,
            "title": "Population",
            "type": "integer"
          },
          "result_ids": {
            "description": "`sql_receipts[].result_id` of every statement this figure is readable out of.",
            "items": {
              "type": "string"
            },
            "title": "Result Ids",
            "type": "array"
          },
          "spec_id": {
            "description": "The run's committed TestSpec this figure was computed under.",
            "title": "Spec Id",
            "type": "string"
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The exceptions' value as text, so a decimal survives the wire. Null for a count-only criterion.",
            "title": "Value"
          }
        },
        "required": [
          "criterion",
          "definition",
          "spec_id",
          "population",
          "count"
        ],
        "title": "JetFigure",
        "type": "object"
      },
      "JetQuality": {
        "additionalProperties": false,
        "description": "Structured execution-quality reporting for one JE-testing result.\n\nDistinguishes a clean, fully evidenced success from a recovered or partially\nvalidated one without changing ``ok`` or inventing figures. Contains only\ncheck names, tool names, outcome categories, and counts — never prompts,\nanswers, evidence bodies, shell output, or client identifiers.",
        "properties": {
          "missing_artifacts": {
            "description": "Required audit artifact classes absent from a quantitative result (``binding`` and/or ``sql_receipts``). Empty when every finding is ``cannot_be_performed`` or when both artifacts are present.",
            "items": {
              "enum": [
                "binding",
                "sql_receipts"
              ],
              "type": "string"
            },
            "title": "Missing Artifacts",
            "type": "array"
          },
          "retried_checks": {
            "description": "Output-contract check families that cost the answer a model re-emission, whether or not the re-emission repaired them. Attribution only — a retry the model then satisfied is a clean answer, so this does not move ``status``.",
            "items": {
              "enum": [
                "specs",
                "scope",
                "cycle",
                "grain",
                "basis",
                "absence",
                "bands",
                "pointer",
                "delivery",
                "figures"
              ],
              "type": "string"
            },
            "title": "Retried Checks",
            "type": "array"
          },
          "status": {
            "description": "``clean`` when nothing was recovered; ``recovered_with_warnings`` when a fail-open check, tool failure, or missing audit artifact was recorded; ``degraded`` when the run salvaged working after a hard failure (see ``JetResult.degraded``).",
            "enum": [
              "clean",
              "recovered_with_warnings",
              "degraded"
            ],
            "title": "Status",
            "type": "string"
          },
          "tool_failures": {
            "description": "Non-success tool outcomes the agent recovered from, aggregated by tool and category.",
            "items": {
              "$ref": "#/components/schemas/JetToolFailure"
            },
            "title": "Tool Failures",
            "type": "array"
          },
          "validation_warnings": {
            "description": "Fail-open output checks that passed the answer through after their corrective retry.",
            "items": {
              "$ref": "#/components/schemas/JetValidationWarning"
            },
            "title": "Validation Warnings",
            "type": "array"
          },
          "withheld_receipt_figures": {
            "default": 0,
            "description": "How many performed figures were published with no readable receipt id — either the statements behind them are not visible to this caller, or the figure was computed without one. The figures themselves are still returned; this counts the ones whose working cannot be inspected.",
            "minimum": 0.0,
            "title": "Withheld Receipt Figures",
            "type": "integer"
          }
        },
        "required": [
          "status"
        ],
        "title": "JetQuality",
        "type": "object"
      },
      "JetResult": {
        "additionalProperties": false,
        "description": "The result of one journal-entry-testing run (``JobKind.JE_TESTING``).\n\nShape-compatible with :class:`IntelligentSearchResult` for the retrieval\ncore — evidences, reasoning, answer, the tool-call trace, the session\nhandle, usage and exhaustion all mean exactly what they mean there — plus\n``sql_receipts``: the statements behind the answer.\n\n``figures`` is the answer's checkable half: one entry per criterion, each\nnaming the receipts its figures are readable out of. There is no ``coverage``\nblock — v1 runs on tables the caller selected, and an honest coverage number\nneeds an orientation pass that reports what was *not* selected.",
        "properties": {
          "agent_usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JetAgentUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "Root-agent model requests split into execution, compaction, and recovery finalization. Null on the fixed pipeline and on results stored before this telemetry existed; use `usage` for all nested LLM cost."
          },
          "answer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The direct, grounded answer to the request. Null only on a run that exhausted its budget before authoring one, or that asked `clarification_questions` instead.",
            "title": "Answer"
          },
          "binding": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LedgerBindingWire"
              },
              {
                "type": "null"
              }
            ],
            "description": "The definitional layer the run committed and computed under — which column is the period, which values mean posted, which clock a timing test was verbed on. Null on a run that answered without binding a ledger, which is only possible before any statement ran."
          },
          "clarification": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The run's clarifying questions as plain text, instead of an answer. Only ever set when the request carried `allow_clarification` and the run needed the user's input to go on; `answer` is null and `evidences` empty alongside it. The same questions, structured, are in `clarification_questions`.",
            "title": "Clarification"
          },
          "clarification_questions": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ClarifyingQuestion"
                },
                "maxItems": 2,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The questions behind `clarification`, at most 2, each with up to 4 suggested answers. Answer them with a follow-up on `session_id` that repeats the query and carries `clarification_answers` (one entry per question, a null answer skips it), or with any follow-up query in your own words. Null on every run that answered.",
            "title": "Clarification Questions"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The agent's self-graded confidence in the answer — how well the evidence and executed statements support it, on the shared six-level scale (certain / very_high / high / medium / low / speculative). Deep search publishes an answer that cites no evidence, claim or receipt at medium at most, and JE testing publishes a run with any `incomplete` criterion at medium at most. Null on exhausted runs and on results stored before the field existed."
          },
          "criteria": {
            "description": "Every requested test and its final disposition, including tests that never reached binding, measurement, or a published figure. Empty only on results stored before this checklist existed.",
            "items": {
              "$ref": "#/components/schemas/JetCriterionOutcome"
            },
            "title": "Criteria",
            "type": "array"
          },
          "degraded": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this result is degraded, when it is. The run broke before it could finalize an answer but had already computed real working, so what is published is that working — `sql_receipts` and `binding` — with `figures` empty and `answer` saying so. Null on every run that finished normally, exhausted ones included.",
            "title": "Degraded"
          },
          "discrepancies": {
            "description": "Where the data contradicted the request's premise or a figure it stated. Empty when nothing did — the run is asked for this explicitly, so an empty list is an answer rather than an omission.",
            "items": {
              "type": "string"
            },
            "title": "Discrepancies",
            "type": "array"
          },
          "evidences": {
            "description": "The material the answer cites, each resolved to the caller's own uploaded file.",
            "items": {
              "$ref": "#/components/schemas/SearchEvidence"
            },
            "title": "Evidences",
            "type": "array"
          },
          "execution_status": {
            "anyOf": [
              {
                "enum": [
                  "performed",
                  "partially_performed",
                  "not_performed"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether the run tested what it was asked to test: ``performed`` when every figure was computed, ``partially_performed`` when some criteria could not be, ``not_performed`` when none could. Read it alongside `quality`, which grades how well a performed test went. JE-testing always sets this on a finished run; other JetResult subclasses (deep search) leave it null, as do results stored before the field existed.",
            "title": "Execution Status"
          },
          "exhausted": {
            "default": false,
            "description": "Step budget hit before the run was satisfied. A successful response, not a failure.",
            "title": "Exhausted",
            "type": "boolean"
          },
          "figures": {
            "description": "One entry per criterion tested, each linked to the receipts its figures are readable out of. Empty on a run that answered without testing anything, or that exhausted its budget first.",
            "items": {
              "$ref": "#/components/schemas/JetFigure"
            },
            "title": "Figures",
            "type": "array"
          },
          "grounding_job_ids": {
            "anyOf": [
              {
                "items": {
                  "format": "uuid",
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ground jobs planned for this search's evidences. Empty when postprocessing is disabled for this caller by deployment policy, explicitly disabled for the run, or no evidence is groundable. Absent on older results. When empty or absent, callers may POST /v1/ground explicitly to locate quotes.",
            "title": "Grounding Job Ids"
          },
          "population_statement": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The population every figure was computed over — file, period, layer, status, basis, grain — in the run's own words. Null only on a run that never authored an answer.",
            "title": "Population Statement"
          },
          "quality": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JetQuality"
              },
              {
                "type": "null"
              }
            ],
            "description": "Structured execution quality: clean vs recovered-with-warnings vs degraded, plus the fail-open checks, tool-failure counts, and missing audit artifacts that produced that status. JE-testing always sets this on a finished run. Other JetResult subclasses (deep search) leave it null. Null also on results stored before the field existed."
          },
          "reasoning": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How the receipted statements chain together into the answer.",
            "title": "Reasoning"
          },
          "result_type": {
            "const": "je_testing",
            "default": "je_testing",
            "title": "Result Type",
            "type": "string"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The conversation this run belongs to. Send it back as the request's `session_id` to ask a follow-up in the same thread.",
            "title": "Session Id"
          },
          "spec_digest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "A short fingerprint of what this run committed to TEST — the rows, grain, clock, encoding, thresholds and time window each criterion was pinned to — with the free-text justifications beside those choices excluded. Two runs of the same question carry the same value when they tested the same thing, so an unstable answer can be told apart from an answer to a quietly different question without re-reading either run. Null on a run that committed no test spec, and on other JetResult subclasses.",
            "title": "Spec Digest"
          },
          "sql_receipts": {
            "description": "Every statement the run executed, in execution order — the answer's working.",
            "items": {
              "$ref": "#/components/schemas/SqlReceipt"
            },
            "title": "Sql Receipts",
            "type": "array"
          },
          "steps_used": {
            "default": 0,
            "description": "Legacy procedure-step count retained for compatibility. It is engine-specific and is not a model-request count; agent runs expose completed root-model requests in `agent_usage`. Read it with `exhausted`, which says whether the configured request budget ran out before the run was satisfied.",
            "title": "Steps Used",
            "type": "integer"
          },
          "tool_calls": {
            "description": "One entry per tool the run invoked, in execution order — the tool's name, a digest of its arguments, how many results came back, and how long it took. The run's shape, not its content.",
            "items": {
              "$ref": "#/components/schemas/ToolCallTrace"
            },
            "title": "Tool Calls",
            "type": "array"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SearchLlmUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What this run spent on LLM calls. Present only when the request asked for it; null means nothing was measured, not that nothing was spent."
          }
        },
        "title": "JetResult",
        "type": "object"
      },
      "JetToolFailure": {
        "additionalProperties": false,
        "description": "How many times one tool returned a non-success outcome this run.",
        "properties": {
          "count": {
            "description": "How many times this tool×outcome pair occurred in the run.",
            "minimum": 1.0,
            "title": "Count",
            "type": "integer"
          },
          "outcome": {
            "description": "Category of the non-success: ``model_retry`` (a call the run corrected: a gate refusal, a rejected argument shape or a validation retry; does not lower `quality.status`), ``command_error`` (non-zero shell exit), ``timeout``, or ``tool_error`` (the tool itself failed, for example a SQL error).",
            "enum": [
              "model_retry",
              "command_error",
              "timeout",
              "tool_error"
            ],
            "title": "Outcome",
            "type": "string"
          },
          "tool": {
            "description": "Tool name that produced the non-success outcome (for example ``run_command``).",
            "title": "Tool",
            "type": "string"
          }
        },
        "required": [
          "tool",
          "outcome",
          "count"
        ],
        "title": "JetToolFailure",
        "type": "object"
      },
      "JetValidationWarning": {
        "additionalProperties": false,
        "description": "One output-contract check that failed open after its corrective retry.",
        "properties": {
          "check": {
            "description": "Stable machine-readable name of the fail-open check that was not satisfied. ``specs`` covers two causes: a finding that names no committed test, and a finding computed for a test the run still declared blocked by a missing parameter.",
            "enum": [
              "specs",
              "scope",
              "cycle",
              "grain",
              "basis",
              "absence",
              "bands",
              "pointer",
              "delivery",
              "figures"
            ],
            "title": "Check",
            "type": "string"
          },
          "status": {
            "const": "failed_open",
            "default": "failed_open",
            "description": "Always ``failed_open``: the check rejected the answer once, then passed it through.",
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "check"
        ],
        "title": "JetValidationWarning",
        "type": "object"
      },
      "Job": {
        "additionalProperties": false,
        "description": "Every slow method returns one of these (spec 12 §1.4).\n\nThere is no ``/parse`` + ``/parse_async`` pair: every job-creating route\nreturns ``202`` with a queued job and accepts ``?wait_seconds=``, returning\n``200`` with a terminal job if the work finished inside the window. The\ncaller's code path is the same either way — read ``status``.",
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "$ref": "#/components/schemas/JobKind",
            "description": "Which operation created this job. Discriminates the result payload."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "automatic_agent": "#/components/schemas/AutomaticAgentResult",
                    "automatic_search": "#/components/schemas/AutomaticSearchResult",
                    "categorize": "#/components/schemas/ndi_service__app__platform_api__results__CategorizeResult",
                    "classify": "#/components/schemas/ClassifyResult",
                    "deep_search_v2": "#/components/schemas/DeepSearchV2Result",
                    "extract": "#/components/schemas/ndi_service__app__platform_api__results__ExtractResult",
                    "file_delete": "#/components/schemas/DeleteFileResult",
                    "file_metadata": "#/components/schemas/FileMetadataResult",
                    "file_replace": "#/components/schemas/ReplaceFileResult",
                    "file_upload": "#/components/schemas/UploadFileResult",
                    "files_delete": "#/components/schemas/DeleteFilesResult",
                    "filtered_search": "#/components/schemas/FilteredSearchResult",
                    "folder_metadata": "#/components/schemas/FolderMetadataResult",
                    "grep": "#/components/schemas/GrepResult",
                    "ground": "#/components/schemas/ndi_service__app__platform_api__results__GroundResult",
                    "hybrid_search": "#/components/schemas/HybridSearchResult",
                    "ingestion": "#/components/schemas/IngestionResult",
                    "intelligent_search": "#/components/schemas/IntelligentSearchResult",
                    "je_testing": "#/components/schemas/JetResult",
                    "kg_build": "#/components/schemas/KnowledgeGraphBuildResult",
                    "ledger_parse_exhibits": "#/components/schemas/LedgerParseExhibitsResult",
                    "ledger_understanding": "#/components/schemas/LedgerUnderstandingResult",
                    "ledger_understanding_reset": "#/components/schemas/LedgerUnderstandingResetResult",
                    "locate": "#/components/schemas/LocateResult",
                    "parse": "#/components/schemas/ndi_service__app__platform_api__results__ParseResult",
                    "qa_file": "#/components/schemas/QaFileResult",
                    "qa_tables": "#/components/schemas/QaTablesResult",
                    "read_file": "#/components/schemas/ReadFileResult",
                    "reconciliation": "#/components/schemas/ReconciliationResult",
                    "run_sql": "#/components/schemas/RunSqlResult",
                    "split": "#/components/schemas/SplitResult",
                    "storage_connection_validate": "#/components/schemas/StorageConnectionValidationResult",
                    "tenant_purge": "#/components/schemas/TenantPurgeResult",
                    "workspace_delete": "#/components/schemas/WorkspaceDeleteResult"
                  },
                  "propertyName": "result_type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/StorageConnectionValidationResult"
                  },
                  {
                    "$ref": "#/components/schemas/FolderMetadataResult"
                  },
                  {
                    "$ref": "#/components/schemas/FileMetadataResult"
                  },
                  {
                    "$ref": "#/components/schemas/ReadFileResult"
                  },
                  {
                    "$ref": "#/components/schemas/HybridSearchResult"
                  },
                  {
                    "$ref": "#/components/schemas/GrepResult"
                  },
                  {
                    "$ref": "#/components/schemas/RunSqlResult"
                  },
                  {
                    "$ref": "#/components/schemas/LocateResult"
                  },
                  {
                    "$ref": "#/components/schemas/ndi_service__app__platform_api__results__ParseResult"
                  },
                  {
                    "$ref": "#/components/schemas/SplitResult"
                  },
                  {
                    "$ref": "#/components/schemas/ClassifyResult"
                  },
                  {
                    "$ref": "#/components/schemas/ndi_service__app__platform_api__results__CategorizeResult"
                  },
                  {
                    "$ref": "#/components/schemas/ndi_service__app__platform_api__results__ExtractResult"
                  },
                  {
                    "$ref": "#/components/schemas/ndi_service__app__platform_api__results__GroundResult"
                  },
                  {
                    "$ref": "#/components/schemas/IngestionResult"
                  },
                  {
                    "$ref": "#/components/schemas/ReconciliationResult"
                  },
                  {
                    "$ref": "#/components/schemas/KnowledgeGraphBuildResult"
                  },
                  {
                    "$ref": "#/components/schemas/LedgerUnderstandingResult"
                  },
                  {
                    "$ref": "#/components/schemas/LedgerUnderstandingResetResult"
                  },
                  {
                    "$ref": "#/components/schemas/LedgerParseExhibitsResult"
                  },
                  {
                    "$ref": "#/components/schemas/UploadFileResult"
                  },
                  {
                    "$ref": "#/components/schemas/ReplaceFileResult"
                  },
                  {
                    "$ref": "#/components/schemas/DeleteFileResult"
                  },
                  {
                    "$ref": "#/components/schemas/DeleteFilesResult"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceDeleteResult"
                  },
                  {
                    "$ref": "#/components/schemas/TenantPurgeResult"
                  },
                  {
                    "$ref": "#/components/schemas/IntelligentSearchResult"
                  },
                  {
                    "$ref": "#/components/schemas/QaFileResult"
                  },
                  {
                    "$ref": "#/components/schemas/QaTablesResult"
                  },
                  {
                    "$ref": "#/components/schemas/FilteredSearchResult"
                  },
                  {
                    "$ref": "#/components/schemas/JetResult"
                  },
                  {
                    "$ref": "#/components/schemas/DeepSearchV2Result"
                  },
                  {
                    "$ref": "#/components/schemas/AutomaticAgentResult"
                  },
                  {
                    "$ref": "#/components/schemas/AutomaticSearchResult"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Present on succeeded while retained. Also present on a running classify or extract job that already published a progressive result (labels or values). Null while queued, after its content is removed, and once the job, or the job it ran for, is cancelled.",
            "title": "Result"
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "kind",
          "status",
          "created_at"
        ],
        "title": "Job",
        "type": "object"
      },
      "JobCost": {
        "additionalProperties": false,
        "description": "An immutable USD price independent of the legacy credit schedule.",
        "properties": {
          "currency": {
            "const": "USD",
            "default": "USD",
            "title": "Currency",
            "type": "string"
          },
          "lines": {
            "description": "The independently priced Parse and operation components, including paid reuse.",
            "items": {
              "$ref": "#/components/schemas/CostLine"
            },
            "title": "Lines",
            "type": "array"
          },
          "pricing_version": {
            "description": "The dollar price-sheet version pinned when this job was accepted.",
            "title": "Pricing Version",
            "type": "string"
          },
          "total_usd": {
            "description": "Sum of the component amounts in USD, serialized as a decimal string.",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,9}0*$",
            "title": "Total Usd",
            "type": "string"
          }
        },
        "required": [
          "pricing_version",
          "total_usd",
          "lines"
        ],
        "title": "JobCost",
        "type": "object"
      },
      "JobDownloadLink": {
        "additionalProperties": false,
        "description": "Short-lived signed URL to one job file, fetchable without API-key headers.",
        "properties": {
          "content_type": {
            "description": "Media type the file is served with.",
            "title": "Content Type",
            "type": "string"
          },
          "disposition": {
            "description": "Disposition the file is served with.",
            "enum": [
              "inline",
              "attachment"
            ],
            "title": "Disposition",
            "type": "string"
          },
          "expires_at": {
            "description": "Expiry of the URL, as Unix epoch seconds.",
            "title": "Expires At",
            "type": "integer"
          },
          "file_name": {
            "description": "Name the file is served under.",
            "title": "File Name",
            "type": "string"
          },
          "url": {
            "description": "Signed download URL. Treat it as a temporary credential. Customer-workspace links recheck storage access and job availability when opened; other links remain valid until expiry.",
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url",
          "expires_at",
          "file_name",
          "content_type",
          "disposition"
        ],
        "title": "JobDownloadLink",
        "type": "object"
      },
      "JobDownloadLinkRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /jobs/{job_id}/download-links``.",
        "properties": {
          "disposition": {
            "default": "inline",
            "description": "Whether a browser should render the file in place or save it. Types unsafe to render are always attachments.",
            "enum": [
              "inline",
              "attachment"
            ],
            "title": "Disposition",
            "type": "string"
          },
          "ref": {
            "description": "Opaque file ref, the last segment of that stable URL.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Ref",
            "type": "string"
          },
          "resource": {
            "description": "Route segment of the job file, as in its stable URL `/v1/jobs/{job_id}/{resource}/{ref}`.",
            "enum": [
              "split-artifacts",
              "ground-crops",
              "ground-transcript",
              "parse-images",
              "parse-transcript",
              "converted-pdf",
              "spreadsheet-cell-maps"
            ],
            "title": "Resource",
            "type": "string"
          }
        },
        "required": [
          "resource",
          "ref"
        ],
        "title": "JobDownloadLinkRequest",
        "type": "object"
      },
      "JobKind": {
        "description": "What a job is doing. Open enum — a new member is additive.",
        "enum": [
          "parse",
          "split",
          "classify",
          "categorize",
          "extract",
          "ground",
          "ingestion",
          "reconciliation",
          "kg_build",
          "file_upload",
          "file_replace",
          "upload_session_complete",
          "file_delete",
          "files_delete",
          "workspace_delete",
          "intelligent_search",
          "folder_metadata",
          "file_metadata",
          "read_file",
          "hybrid_search",
          "grep",
          "run_sql",
          "locate",
          "qa_file",
          "qa_tables",
          "filtered_search",
          "je_testing",
          "je_testing_v2",
          "deep_search_v2",
          "automatic_agent",
          "ledger_understanding",
          "ledger_understanding_reset",
          "ledger_parse_exhibits",
          "tenant_purge",
          "storage_connection_validate"
        ],
        "title": "JobKind",
        "type": "string"
      },
      "JobProgress": {
        "additionalProperties": false,
        "description": "Absent until the job is ``running``.",
        "properties": {
          "items_done": {
            "default": 0,
            "title": "Items Done",
            "type": "integer"
          },
          "items_failed": {
            "default": 0,
            "description": "Quarantined after exhausting retries, for batch kinds. Excluded from items_done.",
            "title": "Items Failed",
            "type": "integer"
          },
          "items_total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Files, for batch kinds.",
            "title": "Items Total"
          },
          "knowledge_graph": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KnowledgeGraphBuildProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Detail only a kg_build reports; null for every other job kind."
          },
          "routing": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AutomaticSearchRouting"
              },
              {
                "type": "null"
              }
            ],
            "description": "The route an automatic search chose, from the moment it chose it, so a caller can show the decision while the chosen pipeline runs; timings arrive with the result's ``routing``. Null for every other job kind."
          },
          "stage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current pipeline stage, for display only.",
            "title": "Stage"
          },
          "units_done": {
            "default": 0,
            "title": "Units Done",
            "type": "integer"
          },
          "units_total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Units Total"
          }
        },
        "title": "JobProgress",
        "type": "object"
      },
      "JobStatus-Input": {
        "description": "``cancelled`` is a first-class terminal status, not a ``failed`` variant.\n\nConflating them makes error-rate metrics lie and forces every client to\nstring-match an error code.",
        "enum": [
          "queued",
          "running",
          "succeeded",
          "failed",
          "cancelled"
        ],
        "title": "JobStatus",
        "type": "string"
      },
      "JobUsage": {
        "additionalProperties": false,
        "description": "How a job's final credits were computed.",
        "properties": {
          "lines": {
            "description": "One line per part. Their credits sum to the job's credits; waived parts remain listed at 0 credits.",
            "items": {
              "$ref": "#/components/schemas/UsageLine"
            },
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "title": "JobUsage",
        "type": "object"
      },
      "JoinEdgeWire": {
        "additionalProperties": false,
        "description": "One expected join of the ledger's graph, measured in both directions.",
        "properties": {
          "left_column": {
            "description": "The column on that table the edge joins on.",
            "title": "Left Column",
            "type": "string"
          },
          "left_columns": {
            "description": "Ordered composite source key; empty means the scalar column.",
            "items": {
              "type": "string"
            },
            "title": "Left Columns",
            "type": "array"
          },
          "left_in_right": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Share of the left column's distinct values that appear in the right.",
            "title": "Left In Right"
          },
          "left_null_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Source rows with a missing key component.",
            "title": "Left Null Rows"
          },
          "left_table": {
            "description": "The table the edge is measured from.",
            "title": "Left Table",
            "type": "string"
          },
          "left_tables": {
            "description": "Selected population members measured together; empty means the scalar table.",
            "items": {
              "type": "string"
            },
            "title": "Left Tables",
            "type": "array"
          },
          "right_column": {
            "description": "The column on that table the edge joins on.",
            "title": "Right Column",
            "type": "string"
          },
          "right_columns": {
            "description": "Ordered composite reference key; empty means the scalar column.",
            "items": {
              "type": "string"
            },
            "title": "Right Columns",
            "type": "array"
          },
          "right_duplicate_keys": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Reference keys appearing more than once, making row enrichment unsafe.",
            "title": "Right Duplicate Keys"
          },
          "right_in_left": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Share of the right column's distinct values that appear in the left.",
            "title": "Right In Left"
          },
          "right_null_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Reference rows with a missing key component.",
            "title": "Right Null Rows"
          },
          "right_table": {
            "description": "The table the edge is measured against.",
            "title": "Right Table",
            "type": "string"
          },
          "unmatched_left": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Distinct left values with no match on the right.",
            "title": "Unmatched Left"
          },
          "unmatched_right": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Distinct right values with no match on the left.",
            "title": "Unmatched Right"
          }
        },
        "required": [
          "left_table",
          "left_column",
          "right_table",
          "right_column"
        ],
        "title": "JoinEdgeWire",
        "type": "object"
      },
      "JsonPointer": {
        "additionalProperties": false,
        "description": "An RFC 6901 pointer into a JSON source; an empty string means the root.",
        "properties": {
          "kind": {
            "const": "json_pointer",
            "default": "json_pointer",
            "title": "Kind",
            "type": "string"
          },
          "pointer": {
            "pattern": "^(?:$|/)",
            "title": "Pointer",
            "type": "string"
          }
        },
        "required": [
          "pointer"
        ],
        "title": "JsonPointer",
        "type": "object"
      },
      "JsonValue": {},
      "JsonlRecord": {
        "additionalProperties": false,
        "properties": {
          "column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Column"
          },
          "kind": {
            "const": "jsonl_record",
            "default": "jsonl_record",
            "title": "Kind",
            "type": "string"
          },
          "row_offset": {
            "title": "Row Offset",
            "type": "integer"
          }
        },
        "required": [
          "row_offset"
        ],
        "title": "JsonlRecord",
        "type": "object"
      },
      "KeyAttempt": {
        "additionalProperties": false,
        "properties": {
          "balanced_share": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Measured balance share, absent when unmeasured.",
            "title": "Balanced Share"
          },
          "columns": {
            "description": "Ordered nominated identity; empty when no candidate was available.",
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "expected_rows": {
            "description": "Complete primary row count.",
            "title": "Expected Rows",
            "type": "integer"
          },
          "measured_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Observed row coverage, absent before key measurement.",
            "title": "Measured Rows"
          },
          "nominated_by": {
            "description": "Origin of the nomination, not its acceptance: the census search, a reviewer, the discovery structure proposal, or the model's key recovery.",
            "enum": [
              "automatic",
              "human",
              "proposal",
              "model"
            ],
            "title": "Nominated By",
            "type": "string"
          },
          "null_counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Exact null counts per column, not a row-wise union.",
            "title": "Null Counts",
            "type": "object"
          },
          "outcome": {
            "description": "Measured gate result or incomplete evidence.",
            "enum": [
              "qualified",
              "rejected",
              "unmeasured"
            ],
            "title": "Outcome",
            "type": "string"
          },
          "reason": {
            "description": "Aggregate explanation; never journal values.",
            "title": "Reason",
            "type": "string"
          }
        },
        "required": [
          "columns",
          "nominated_by",
          "outcome",
          "reason",
          "expected_rows"
        ],
        "title": "KeyAttempt",
        "type": "object"
      },
      "KnowledgeGraphBuildJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "kg_build",
            "default": "kg_build",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KnowledgeGraphBuildResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "KnowledgeGraphBuildJob",
        "type": "object"
      },
      "KnowledgeGraphBuildProgress": {
        "additionalProperties": false,
        "description": "Where a ``kg_build`` is, beyond what ``stage`` alone can say.\n\nA graph build runs for minutes to hours through a fixed sequence of phases,\nand ``stage`` names only the current one. Turning that into \"how far along\"\notherwise means hard-coding the build engine's phase order in every client —\nan order that lives in another package and is free to gain a phase. So the\nposition is reported rather than inferred.\n\nThe counters are deliberately not a percentage. The phases are wildly unequal\n(extraction is ~60% of a build, and its per-document cost varies 25x with how\ndense the documents are), so weighting them is a presentation decision, made\nagainst measurements, that belongs to whoever is drawing the bar.",
        "properties": {
          "countable": {
            "description": "Whether items_total/items_done describe this phase. False for the phases that are a single step, which have no unit to count — draw those as indeterminate rather than as a bar stuck at zero.",
            "title": "Countable",
            "type": "boolean"
          },
          "documents": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Documents registered from the corpus, once the registering phase has run.",
            "title": "Documents"
          },
          "mentions": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Mentions extracted across the corpus, once the validating phase has run.",
            "title": "Mentions"
          },
          "phase_count": {
            "description": "How many phases a build passes through before it is done. Currently 9.",
            "title": "Phase Count",
            "type": "integer"
          },
          "phase_index": {
            "description": "0-based position of the current phase in the build's fixed run order; equals phase_count when done.",
            "title": "Phase Index",
            "type": "integer"
          },
          "step": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The span in flight inside a single-step phase, reported by the running step itself. Null when the phase counts its own units, or before the step has reported one.",
            "title": "Step"
          },
          "step_done": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Units of `step` finished, when it has countable units.",
            "title": "Step Done"
          },
          "step_total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Units `step` has to get through, when that is known.",
            "title": "Step Total"
          }
        },
        "required": [
          "phase_index",
          "phase_count",
          "countable"
        ],
        "title": "KnowledgeGraphBuildProgress",
        "type": "object"
      },
      "KnowledgeGraphBuildRequest": {
        "additionalProperties": false,
        "description": "Request body for ``POST /v1/workspaces/{id}/knowledge-graph/builds``.",
        "properties": {
          "force": {
            "default": false,
            "description": "Clear the workspace's knowledge-graph store and rebuild from scratch. The default resumes from the durable store, reusing every extraction, embedding, and resolution verdict already paid for; a force build discards that cache — use it only when the store is suspected corrupt or the ontology's meaning changed under a version it did not re-key.",
            "title": "Force",
            "type": "boolean"
          }
        },
        "title": "KnowledgeGraphBuildRequest",
        "type": "object"
      },
      "KnowledgeGraphBuildResult": {
        "additionalProperties": false,
        "description": "The corpus-level graph build: what one snapshot covered.\n\nThe graph is a property of the whole corpus, not a per-file derivative, so\nthis reports totals rather than per-file outcomes — with one exception:\n``files_failed`` is per-file because a build now finishes without the files it\ncould not process, and \"which files is this graph blind to\" is otherwise\nunanswerable from the outside. A file listed there is excluded from\n``files_covered`` and stays marked as needing a rebuild.\n\n``snapshot_id`` is the new graph's cache key — the same value ``kg_info``\nreturns — so a caller can tell the build actually advanced the served graph.",
        "properties": {
          "edge_count": {
            "default": 0,
            "title": "Edge Count",
            "type": "integer"
          },
          "files_covered": {
            "description": "Source files whose ledger version matched the build-time corpus at finalize; files replaced during the build are excluded and will show as needing a rebuild.",
            "title": "Files Covered",
            "type": "integer"
          },
          "files_failed": {
            "description": "Files quarantined after exhausting their retries. Not in the graph, and not marked covered.",
            "items": {
              "$ref": "#/components/schemas/KnowledgeGraphFileFailure"
            },
            "title": "Files Failed",
            "type": "array"
          },
          "node_count": {
            "default": 0,
            "title": "Node Count",
            "type": "integer"
          },
          "rebuilt": {
            "default": false,
            "description": "True when a force build cleared the prior store first.",
            "title": "Rebuilt",
            "type": "boolean"
          },
          "result_type": {
            "const": "kg_build",
            "default": "kg_build",
            "title": "Result Type",
            "type": "string"
          },
          "snapshot_id": {
            "title": "Snapshot Id",
            "type": "string"
          },
          "status": {
            "default": "published",
            "description": "published when this build wrote a snapshot. empty_no_mentions when every planned document extracted and none produced a mention, so the job succeeded without publishing a snapshot.",
            "enum": [
              "published",
              "empty_no_mentions"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "snapshot_id",
          "files_covered"
        ],
        "title": "KnowledgeGraphBuildResult",
        "type": "object"
      },
      "KnowledgeGraphConfig": {
        "additionalProperties": false,
        "description": "A workspace's knowledge-graph build policy.\n\nThe defaults keep the whole corpus in scope and build the graph after every\ningestion, so fact search and deep search have it to navigate by. Set\n``auto_build=false`` for a workspace that builds only on request.\n``exclude_path_prefixes`` and ``exclude_categories`` are the workspace-wide\nskip rules a file's ``graph_inclusion`` can override — a file matching either\nis left out of the graph corpus unless it is explicitly ``include``\\ d.",
        "properties": {
          "auto_build": {
            "default": true,
            "description": "Build the graph automatically after each ingestion completes. On by default; turn it off to build only on request (a build is billable and long-running). Ingestion skips the automatic build once the graph corpus reaches the deployment's kg.auto_build.max_corpus_files limit; an explicit build still runs.",
            "title": "Auto Build",
            "type": "boolean"
          },
          "exclude_categories": {
            "description": "Files whose category is any of these are kept out of the graph corpus (override per file).",
            "items": {
              "maxLength": 1024,
              "type": "string"
            },
            "maxItems": 128,
            "title": "Exclude Categories",
            "type": "array"
          },
          "exclude_path_prefixes": {
            "description": "Files whose path starts with any of these are kept out of the graph corpus (override per file).",
            "items": {
              "maxLength": 1024,
              "type": "string"
            },
            "maxItems": 128,
            "title": "Exclude Path Prefixes",
            "type": "array"
          }
        },
        "title": "KnowledgeGraphConfig",
        "type": "object"
      },
      "KnowledgeGraphFileFailure": {
        "additionalProperties": false,
        "description": "One source file the build could not get into the graph.",
        "properties": {
          "error": {
            "description": "The verbatim final cause, as the failing step reported it.",
            "title": "Error",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "phase": {
            "description": "Where it failed: 'classifying' (never registered) or 'extracting'.",
            "enum": [
              "classifying",
              "extracting"
            ],
            "title": "Phase",
            "type": "string"
          }
        },
        "required": [
          "path",
          "phase",
          "error"
        ],
        "title": "KnowledgeGraphFileFailure",
        "type": "object"
      },
      "LedgerAssessmentWire": {
        "additionalProperties": false,
        "description": "Evidence-based assessment independent of job success and structural blocking.",
        "properties": {
          "completed_checks": {
            "default": 0,
            "description": "Statements completed, including zero-finding results.",
            "title": "Completed Checks",
            "type": "integer"
          },
          "execution_coverage": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Completed over planned statements; null when unknown or none planned.",
            "title": "Execution Coverage"
          },
          "failed_checks": {
            "default": 0,
            "description": "Planned statements that failed execution.",
            "title": "Failed Checks",
            "type": "integer"
          },
          "header_duplicate_keys": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Excess header rows on the complete declared tuple.",
            "title": "Header Duplicate Keys"
          },
          "header_status": {
            "default": "unmeasured",
            "description": "Declared header tuple's exact coverage and cardinality verdict.",
            "enum": [
              "not_required",
              "unmeasured",
              "complete",
              "partial",
              "unsafe",
              "failed"
            ],
            "title": "Header Status",
            "type": "string"
          },
          "header_unmatched_lines": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unmatched lines retained by optional LEFT JOIN enrichment.",
            "title": "Header Unmatched Lines"
          },
          "not_run_checks": {
            "default": 0,
            "description": "Planned statements withheld after an earlier resource failure.",
            "title": "Not Run Checks",
            "type": "integer"
          },
          "planned_checks": {
            "default": 0,
            "description": "Statements planned, excluding missing-prerequisite skips.",
            "title": "Planned Checks",
            "type": "integer"
          },
          "population_count": {
            "default": 0,
            "description": "Total candidate count before bounding the evidence list.",
            "title": "Population Count",
            "type": "integer"
          },
          "populations": {
            "description": "Bounded same-scope candidate evidence.",
            "items": {
              "$ref": "#/components/schemas/PopulationCandidateWire"
            },
            "title": "Populations",
            "type": "array"
          },
          "procedures": {
            "additionalProperties": {
              "$ref": "#/components/schemas/ProcedureReadinessWire"
            },
            "description": "Procedure-specific readiness, not a JET gate.",
            "title": "Procedures",
            "type": "object"
          },
          "reasons": {
            "description": "Why the summary is not fully ready.",
            "items": {
              "type": "string"
            },
            "title": "Reasons",
            "type": "array"
          },
          "skipped_checks": {
            "default": 0,
            "description": "Checks not planned because prerequisites were absent.",
            "title": "Skipped Checks",
            "type": "integer"
          },
          "source_review_available": {
            "default": false,
            "description": "Whether this completed current reading can open the source-review correction flow.",
            "title": "Source Review Available",
            "type": "boolean"
          },
          "status": {
            "default": "unknown",
            "description": "Summary; inspect procedure readiness and execution coverage before relying on results.",
            "enum": [
              "ready",
              "limited",
              "needs_scope",
              "needs_source_selection",
              "needs_decision",
              "execution_failed",
              "unknown"
            ],
            "title": "Status",
            "type": "string"
          },
          "structure_review_available": {
            "default": false,
            "description": "Whether complete measured schema supports a structural proposal, not key acceptance.",
            "title": "Structure Review Available",
            "type": "boolean"
          }
        },
        "title": "LedgerAssessmentWire",
        "type": "object"
      },
      "LedgerBindingWire": {
        "additionalProperties": false,
        "description": "The definitional layer a run committed, echoed for the caller to read.\n\nThis is the answer to \"on what definitions does this figure rest\" — the\nquestion the prose relay of the old playbook could not answer, and the reason\nthe binding is a validated artifact rather than a paragraph. Every pin was\nchecked against the tables' own profiles before the run was allowed to\ncompute anything: the columns exist with compatible types, the period roles\npartition the observed domain, each clock's declared grain matches its\ncolumn, and every encoding value occurs in its column.\n\nPublished as flat slot listings rather than as a mirror of the internal\nmodel's tree. Two reasons, both practical: a reader wants \"which column is\nthe approval clock\" answered in one place rather than by walking a nested\nobject, and a slot the design adds later becomes another row here instead of\na change to this contract.",
        "properties": {
          "columns": {
            "description": "Every column pinned to a slot, in slot order.",
            "items": {
              "$ref": "#/components/schemas/BoundColumn"
            },
            "title": "Columns",
            "type": "array"
          },
          "notes": {
            "description": "Deviations the run observed while orienting.",
            "items": {
              "type": "string"
            },
            "title": "Notes",
            "type": "array"
          },
          "periods": {
            "description": "The period domain, in period order, with roles.",
            "items": {
              "$ref": "#/components/schemas/BoundPeriod"
            },
            "title": "Periods",
            "type": "array"
          },
          "policy_sheets": {
            "description": "Documents the run treated as settling parameters (a sequence policy, a topside register).",
            "items": {
              "type": "string"
            },
            "title": "Policy Sheets",
            "type": "array"
          },
          "revised_because": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the binding was replaced mid-run, when it was. Null on a run that bound once.",
            "title": "Revised Because"
          },
          "tables": {
            "items": {
              "$ref": "#/components/schemas/BoundTable"
            },
            "title": "Tables",
            "type": "array"
          },
          "value_sets": {
            "description": "Encoding candidates and layer memberships. More than one entry under 'encodings.manual' means the run kept both readings and resolved them per test.",
            "items": {
              "$ref": "#/components/schemas/BoundValueSet"
            },
            "title": "Value Sets",
            "type": "array"
          }
        },
        "title": "LedgerBindingWire",
        "type": "object"
      },
      "LedgerPackageProposals": {
        "additionalProperties": false,
        "properties": {
          "auto_confirmation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AutoConfirmation"
              },
              {
                "type": "null"
              }
            ],
            "description": "Automatic confirmation outcome and review reason."
          },
          "candidates": {
            "description": "Validated nominations in model rank order.",
            "items": {
              "$ref": "#/components/schemas/PackageCandidate"
            },
            "maxItems": 3,
            "title": "Candidates",
            "type": "array"
          },
          "catalog_revision": {
            "description": "Accessible catalog revision used for nomination.",
            "title": "Catalog Revision",
            "type": "string"
          },
          "duration_ms": {
            "default": 0,
            "description": "Elapsed discovery time in milliseconds.",
            "title": "Duration Ms",
            "type": "integer"
          },
          "heuristic_fallback": {
            "default": false,
            "description": "Whether composition ran over rank-ordered catalog sources because triage nominated none.",
            "title": "Heuristic Fallback",
            "type": "boolean"
          },
          "input_tokens": {
            "default": 0,
            "description": "Total input tokens across model calls and retries.",
            "title": "Input Tokens",
            "type": "integer"
          },
          "model_slug": {
            "description": "Model used to nominate packages.",
            "title": "Model Slug",
            "type": "string"
          },
          "output_tokens": {
            "default": 0,
            "description": "Total output tokens across model calls and retries.",
            "title": "Output Tokens",
            "type": "integer"
          },
          "rejected": {
            "description": "Nominations refused by catalog validation.",
            "items": {
              "$ref": "#/components/schemas/RejectedCandidate"
            },
            "title": "Rejected",
            "type": "array"
          },
          "tie_break": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PackageTieBreak"
              },
              {
                "type": "null"
              }
            ],
            "description": "Model choice between competing high-confidence packages; absent when no tie was offered."
          },
          "triaged_out": {
            "description": "Bounded sample of omitted source handles and short reasons.",
            "items": {
              "type": "string"
            },
            "title": "Triaged Out",
            "type": "array"
          },
          "triaged_out_count": {
            "default": 0,
            "description": "Total sources omitted from composition, including those beyond the displayed sample.",
            "title": "Triaged Out Count",
            "type": "integer"
          },
          "warnings": {
            "description": "Discovery limitations, including heuristic fallback after empty triage.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "model_slug",
          "catalog_revision"
        ],
        "title": "LedgerPackageProposals",
        "type": "object"
      },
      "LedgerPackageScope": {
        "additionalProperties": false,
        "description": "A package's source files: every file under the prefix plus every explicit path.",
        "properties": {
          "path_prefix": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Folder containing the package, relative to the workspace root.",
            "title": "Path Prefix"
          },
          "paths": {
            "description": "Exact source paths in the package, added to every path under the prefix.",
            "items": {
              "type": "string"
            },
            "title": "Paths",
            "type": "array"
          },
          "selection_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Protected, immutable source-role selection reference.",
            "title": "Selection Id"
          }
        },
        "title": "LedgerPackageScope",
        "type": "object"
      },
      "LedgerParseExhibitsResult": {
        "additionalProperties": false,
        "description": "Which parse run's GL parse examples are published, read from the manifest that commits them.\n\nThe examples themselves stay behind the explorer routes; this names what a\nsucceeded job made readable, so success always has something to point at.",
        "properties": {
          "journals_total": {
            "description": "Journals the published examples cover, equal to the parse's own count.",
            "minimum": 0.0,
            "title": "Journals Total",
            "type": "integer"
          },
          "parse_run_id": {
            "description": "The parse run whose journals the published examples rank and locate.",
            "title": "Parse Run Id",
            "type": "string"
          },
          "result_type": {
            "const": "ledger_parse_exhibits",
            "default": "ledger_parse_exhibits",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "parse_run_id",
          "journals_total"
        ],
        "title": "LedgerParseExhibitsResult",
        "type": "object"
      },
      "LedgerUnderstandingConfig": {
        "additionalProperties": false,
        "description": "A workspace's ledger-understanding policy.\n\nOn by default in its cheapest form: ``auto`` costs a workspace with no ledger\nin it nothing at all, because the test for \"is there a ledger here\" is the\ncensus's own pure predicate over sidecars that ingestion already wrote.",
        "properties": {
          "engine": {
            "default": "measured",
            "description": "Discovery method; selected packages always run measured validation.",
            "enum": [
              "measured",
              "llm"
            ],
            "title": "Engine",
            "type": "string"
          },
          "gl_parsing": {
            "default": true,
            "description": "Whether the stage should also map each journal's account/debit-credit groups to balanced sub-journals and publish the mapping as a derived table.",
            "title": "Gl Parsing",
            "type": "boolean"
          },
          "package_confirmation": {
            "default": "required",
            "description": "Who confirms an llm-discovered package before GL parsing: a person, or the model on its own. When a person must, parsing runs only on the mapping that person confirmed.",
            "enum": [
              "required",
              "automatic"
            ],
            "title": "Package Confirmation",
            "type": "string"
          },
          "package_scope": {
            "$ref": "#/components/schemas/LedgerPackageScope",
            "description": "Default package selection for understanding, including ingestion-triggered runs."
          },
          "prepared_relationships": {
            "description": "Reviewed large-table relationships to prepare before JET starts. Empty disables preparation.",
            "items": {
              "$ref": "#/components/schemas/PreparedRelationshipConfig"
            },
            "maxItems": 4,
            "title": "Prepared Relationships",
            "type": "array"
          },
          "trigger": {
            "default": "auto",
            "description": "When an ingestion should chain the stage: only for a workspace that holds a journal-line table, after every ingestion that landed files, or never.",
            "enum": [
              "auto",
              "always",
              "off"
            ],
            "title": "Trigger",
            "type": "string"
          }
        },
        "title": "LedgerUnderstandingConfig",
        "type": "object"
      },
      "LedgerUnderstandingReport": {
        "additionalProperties": false,
        "properties": {
          "applied_decisions": {
            "description": "What this reading did with each decision it folded, including the ones it could not apply.",
            "items": {
              "$ref": "#/components/schemas/AppliedDecisionWire"
            },
            "title": "Applied Decisions",
            "type": "array"
          },
          "artifact_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compatibility version that produced this report; absent on legacy job results.",
            "title": "Artifact Version"
          },
          "assessment": {
            "$ref": "#/components/schemas/LedgerAssessmentWire",
            "description": "Readiness and execution coverage; legacy readings are unknown."
          },
          "auto_decisions": {
            "description": "Automatic choices, suggestions and refusals from this reading.",
            "items": {
              "$ref": "#/components/schemas/AutoDecisionWire"
            },
            "title": "Auto Decisions",
            "type": "array"
          },
          "blocking": {
            "description": "Mirrors the integrity report's structural verdict, so a caller can branch on one field.",
            "title": "Blocking",
            "type": "boolean"
          },
          "conventions": {
            "$ref": "#/components/schemas/ConventionsWire",
            "description": "The settled reading of what the package's numbers mean."
          },
          "current_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compatibility version of the server that returned this response.",
            "title": "Current Version"
          },
          "engine": {
            "default": "measured",
            "description": "Configured discovery engine for this reading.",
            "enum": [
              "measured",
              "llm"
            ],
            "title": "Engine",
            "type": "string"
          },
          "integrity": {
            "$ref": "#/components/schemas/IntegrityReportWire",
            "description": "The integrity battery's findings and the checks it could not run."
          },
          "join_graph": {
            "description": "The expected joins between the package's tables, with their ratios.",
            "items": {
              "$ref": "#/components/schemas/JoinEdgeWire"
            },
            "title": "Join Graph",
            "type": "array"
          },
          "open_questions": {
            "description": "What the data could not settle and a reader must decide.",
            "items": {
              "$ref": "#/components/schemas/OpenQuestionWire"
            },
            "title": "Open Questions",
            "type": "array"
          },
          "package_fingerprint": {
            "description": "Identifies the exact selected files this reading measured. It moves whenever one of those files is re-ingested, made visible, or replaced.",
            "title": "Package Fingerprint",
            "type": "string"
          },
          "parsing": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSummaryWire"
              },
              {
                "type": "null"
              }
            ],
            "description": "The general-ledger parsing summary, or null when the workspace has the pass switched off or the package left a precondition open."
          },
          "pending_decisions": {
            "default": 0,
            "description": "Decisions stored for this workspace that this reading did not fold. Zero on a reading that is current with every answer given.",
            "title": "Pending Decisions",
            "type": "integer"
          },
          "preparations": {
            "description": "Reusable relationship preparations requested for this package; empty when none were configured.",
            "items": {
              "$ref": "#/components/schemas/PreparationSummaryWire"
            },
            "title": "Preparations",
            "type": "array"
          },
          "produced_at": {
            "description": "When the stage finished measuring this package.",
            "format": "date-time",
            "title": "Produced At",
            "type": "string"
          },
          "proposals": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LedgerPackageProposals"
              },
              {
                "type": "null"
              }
            ],
            "description": "Sidecar-only nominations awaiting human source selection and measurement."
          },
          "reading_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Immutable reading identity to echo when answering source-selection HITL; absent on legacy reports.",
            "title": "Reading Id"
          },
          "rerun_required": {
            "default": false,
            "description": "Whether a new understanding run is needed to obtain a current report.",
            "title": "Rerun Required",
            "type": "boolean"
          },
          "scope": {
            "$ref": "#/components/schemas/LedgerPackageScope",
            "description": "Source selection this report describes; independent packages have independent readings."
          },
          "settled_structure": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StructureProposal"
              },
              {
                "type": "null"
              }
            ],
            "description": "The journal key, account, amount and optional columns this reading settled, spelled as a structure proposal so it can pre-fill a mapping edit. Null on a discovery reading or when no complete mapping settled."
          },
          "stale": {
            "description": "Whether the workspace has moved since this reading was measured. A stale report is still returned, because an old measurement a reader can date beats no answer at all.",
            "title": "Stale",
            "type": "boolean"
          },
          "stale_reason": {
            "anyOf": [
              {
                "enum": [
                  "package",
                  "version",
                  "decisions"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why it is stale, when it is: 'package' means files were ingested, replaced or made visible since; 'decisions' means somebody has answered a review this reading did not fold. They are different actions — the first is re-measured by a plain run, the second by applying the decisions. 'version' means this build's measurement rules changed. Precedence is package, version, then decisions; the version fields and pending decision count retain the other reasons when several apply.",
            "title": "Stale Reason"
          },
          "tables": {
            "description": "Every queryable table in the package, with its grain figures.",
            "items": {
              "$ref": "#/components/schemas/TableCardWire"
            },
            "title": "Tables",
            "type": "array"
          }
        },
        "required": [
          "package_fingerprint",
          "produced_at",
          "stale",
          "blocking",
          "tables",
          "conventions",
          "integrity",
          "join_graph",
          "open_questions"
        ],
        "title": "LedgerUnderstandingReport",
        "type": "object"
      },
      "LedgerUnderstandingResetResult": {
        "additionalProperties": false,
        "description": "What one ledger-understanding reset removed.\n\nCounted rather than merely reported done, for ``DeleteFileResult``'s reason: a\ncaller who asked for a reset can see it happened. ``verified`` comes from an\nindependent re-read of the prefix, and a false one is an alertable fact on a\njob that still succeeded — failing the job would hide these counts.",
        "properties": {
          "decisions_deleted": {
            "default": 0,
            "description": "Stored review answers cleared across every package; the rows stay, emptied.",
            "title": "Decisions Deleted",
            "type": "integer"
          },
          "jobs_cancelled": {
            "description": "Runs stopped because they were reading what this reset removed.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Jobs Cancelled",
            "type": "array"
          },
          "objects_deleted": {
            "default": 0,
            "description": "Stored objects removed across the stage's own prefix and the je-testing prep prefix.",
            "title": "Objects Deleted",
            "type": "integer"
          },
          "result_type": {
            "const": "ledger_understanding_reset",
            "default": "ledger_understanding_reset",
            "title": "Result Type",
            "type": "string"
          },
          "verified": {
            "default": false,
            "description": "False is a failed reset and must alert.",
            "title": "Verified",
            "type": "boolean"
          },
          "workspace_id": {
            "description": "The workspace whose ledger reading was removed.",
            "format": "uuid",
            "title": "Workspace Id",
            "type": "string"
          }
        },
        "required": [
          "workspace_id"
        ],
        "title": "LedgerUnderstandingResetResult",
        "type": "object"
      },
      "LedgerUnderstandingResult": {
        "additionalProperties": false,
        "description": "One package's settled reading, as the understanding job publishes it.\n\nThe result IS the report: the route's ``GET`` and ``GET /v1/jobs/{id}``\nanswer with the same object, so a caller that polled the job never has to\ncall a second endpoint to learn what the run concluded.",
        "properties": {
          "follow_up_job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Selected-package measurement job chained by discovery.",
            "title": "Follow Up Job Id"
          },
          "report": {
            "$ref": "#/components/schemas/LedgerUnderstandingReport",
            "description": "The package's tables, conventions, integrity findings and open questions."
          },
          "result_type": {
            "const": "ledger_understanding",
            "default": "ledger_understanding",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "report"
        ],
        "title": "LedgerUnderstandingResult",
        "type": "object"
      },
      "LocatePiece": {
        "additionalProperties": false,
        "description": "A piece a previous locate offered, as its `pages[]` entry named it.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "maxLength": 1024,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The piece's `component` (a tab or section); null when it had none.",
            "title": "Component"
          },
          "number": {
            "description": "The piece's `number`: a page, or a text file's window.",
            "minimum": 1.0,
            "title": "Number",
            "type": "integer"
          },
          "path": {
            "description": "The file's uploaded source path.",
            "maxLength": 1024,
            "minLength": 1,
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path",
          "number"
        ],
        "title": "LocatePiece",
        "type": "object"
      },
      "LocateRead": {
        "additionalProperties": false,
        "description": "A read already done: pages of a paged file, a line span of a text file, or the whole file (neither given).",
        "properties": {
          "component": {
            "anyOf": [
              {
                "maxLength": 1024,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The tab or section read; null for the file's own text, or every tab of a whole read.",
            "title": "Component"
          },
          "line_end": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last line read; null to the end.",
            "title": "Line End"
          },
          "line_start": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "First line read; null from line 1.",
            "title": "Line Start"
          },
          "pages": {
            "anyOf": [
              {
                "items": {
                  "minimum": 1.0,
                  "type": "integer"
                },
                "maxItems": 1000,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The page numbers that were read.",
            "title": "Pages"
          },
          "path": {
            "description": "The file's uploaded source path.",
            "maxLength": 1024,
            "minLength": 1,
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "LocateRead",
        "type": "object"
      },
      "LocateRequest": {
        "additionalProperties": false,
        "description": "Request for ``locate``: where in the workspace a piece of information is.\n\nThe navigator NDI's own agent calls as ``ndi-locate``, over the files the caller may see. It is stateless: what a\ncaller was already offered (``exclude``) and has read (``already_read``) is left out of the answer only when sent\nback, as a run's memory does it for NDI's agent. A call that leaves out nothing is the caller's opening and rates\nmore files. ``text`` gives the best pages in full unless ``pointer`` asks for previews only.",
        "properties": {
          "already_read": {
            "description": "Reads already done: their pieces are left out, and the navigator is told they did not settle the need.",
            "items": {
              "$ref": "#/components/schemas/LocateRead"
            },
            "maxItems": 1000,
            "title": "Already Read",
            "type": "array"
          },
          "every": {
            "default": false,
            "description": "The need names a kind of file and every one is wanted (each invoice, every statement): the navigator rates each file of that kind and lists the members in `population`.",
            "title": "Every",
            "type": "boolean"
          },
          "exclude": {
            "description": "Pieces earlier locates offered, left out of this answer.",
            "items": {
              "$ref": "#/components/schemas/LocatePiece"
            },
            "maxItems": 1000,
            "title": "Exclude",
            "type": "array"
          },
          "k": {
            "default": 12,
            "description": "How many pieces to name.",
            "maximum": 24.0,
            "minimum": 1.0,
            "title": "K",
            "type": "integer"
          },
          "need": {
            "description": "What is still needed, in a few words: a year, an entity, a line item, a definition.",
            "maxLength": 400,
            "minLength": 1,
            "title": "Need",
            "type": "string"
          },
          "path_prefix": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only files under this folder, workspace-relative; `paths` adds files. Omit both for the whole workspace.",
            "title": "Path Prefix"
          },
          "paths": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 1024,
                  "minLength": 1,
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Only these uploaded files (with `path_prefix`, its folder's files too). Unknown or inaccessible paths are refused.",
            "title": "Paths"
          },
          "pointer": {
            "default": false,
            "description": "Name every page in `text` by its opening lines only. Without it, the best pages come in full, as a task's first locate wants them; later locates pass it, so page text does not pile up in an agent's context.",
            "title": "Pointer",
            "type": "boolean"
          },
          "question": {
            "anyOf": [
              {
                "maxLength": 4096,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The whole question the need is part of; every decision weighs the need within it. Omit it and the need is the whole question.",
            "title": "Question"
          }
        },
        "required": [
          "need"
        ],
        "title": "LocateRequest",
        "type": "object"
      },
      "LocateResponse": {
        "additionalProperties": false,
        "description": "Response of ``locate``: the reply NDI's agent reads, and the same findings as fields.",
        "properties": {
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The external operation job.",
            "title": "Job Id"
          },
          "pages": {
            "description": "The pieces named, best first.",
            "items": {
              "$ref": "#/components/schemas/LocatedPiece"
            },
            "title": "Pages",
            "type": "array"
          },
          "population": {
            "description": "Set when answering needs every file of a kind (each invoice, every contract): the members, best first.",
            "items": {
              "$ref": "#/components/schemas/LocatedMember"
            },
            "title": "Population",
            "type": "array"
          },
          "population_unrated": {
            "default": 0,
            "description": "Files in folders rated likely to hold members that the budget ran out before rating: when above 0, `population` is incomplete; narrow the need to a folder, kind or period and locate again with `every`.",
            "title": "Population Unrated",
            "type": "integer"
          },
          "tables": {
            "description": "The tables rated for the need, best first.",
            "items": {
              "$ref": "#/components/schemas/LocatedTableRef"
            },
            "title": "Tables",
            "type": "array"
          },
          "text": {
            "description": "The reply as NDI's own agent reads it: each piece with the command that reads it and its text (the best pages in full, the rest by their opening lines; every page by its opening lines with `pointer`), then a population's members and the tables to query.",
            "title": "Text",
            "type": "string"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "text",
          "pages",
          "tables",
          "population"
        ],
        "title": "LocateResponse",
        "type": "object"
      },
      "LocateResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "$ref": "#/components/schemas/LocateResponse",
            "description": "The operation response returned to the caller, retained with its job."
          },
          "result_type": {
            "const": "locate",
            "default": "locate",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "output"
        ],
        "title": "LocateResult",
        "type": "object"
      },
      "LocatedMember": {
        "additionalProperties": false,
        "description": "A file rated a member when the question needs every file of a kind.",
        "properties": {
          "path": {
            "description": "The file's uploaded source path.",
            "title": "Path",
            "type": "string"
          },
          "score": {
            "description": "How likely the file is a member, 0 to 1.",
            "title": "Score",
            "type": "number"
          }
        },
        "required": [
          "path",
          "score"
        ],
        "title": "LocatedMember",
        "type": "object"
      },
      "LocatedPiece": {
        "additionalProperties": false,
        "description": "A piece the navigator named: a page of a paged document, or a line window of a text file.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The tab or section a read of the piece names; null when the file's text is one.",
            "title": "Component"
          },
          "head": {
            "description": "The piece's opening text, cut where the reply text cuts it.",
            "title": "Head",
            "type": "string"
          },
          "line_end": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "A window's last line, inclusive.",
            "title": "Line End"
          },
          "line_start": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "A window's first line, as read-file numbers lines.",
            "title": "Line Start"
          },
          "number": {
            "description": "The page number, or the window's number in a text file.",
            "title": "Number",
            "type": "integer"
          },
          "paged": {
            "description": "True for a page (read it by `number`); false for a window of lines.",
            "title": "Paged",
            "type": "boolean"
          },
          "path": {
            "description": "Uploaded source path of the file.",
            "title": "Path",
            "type": "string"
          },
          "score": {
            "description": "How likely the piece holds what is needed, 0 to 1.",
            "title": "Score",
            "type": "number"
          }
        },
        "required": [
          "path",
          "paged",
          "number",
          "score",
          "head"
        ],
        "title": "LocatedPiece",
        "type": "object"
      },
      "LocatedTableRef": {
        "additionalProperties": false,
        "description": "A queryable table the navigator rated for the need.",
        "properties": {
          "columns": {
            "description": "Every column of the table, in order.",
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "path": {
            "description": "Uploaded source path of the file holding it.",
            "title": "Path",
            "type": "string"
          },
          "relevant_columns": {
            "description": "The columns a query for the need reads, when rated.",
            "items": {
              "type": "string"
            },
            "title": "Relevant Columns",
            "type": "array"
          },
          "score": {
            "description": "How likely its rows answer the need, 0 to 1.",
            "title": "Score",
            "type": "number"
          },
          "sql_table": {
            "description": "The table's name in SQL queries.",
            "title": "Sql Table",
            "type": "string"
          },
          "tab": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workbook tab, when it is one.",
            "title": "Tab"
          }
        },
        "required": [
          "sql_table",
          "path",
          "score",
          "columns",
          "relevant_columns"
        ],
        "title": "LocatedTableRef",
        "type": "object"
      },
      "ManagedWorkspaceStorage": {
        "additionalProperties": false,
        "properties": {
          "type": {
            "const": "managed",
            "default": "managed",
            "title": "Type",
            "type": "string"
          }
        },
        "title": "ManagedWorkspaceStorage",
        "type": "object"
      },
      "MappingChange": {
        "additionalProperties": false,
        "properties": {
          "confirmed": {
            "description": "Columns the reviewer confirmed for this role, in order; debit before credit.",
            "items": {
              "type": "string"
            },
            "title": "Confirmed",
            "type": "array"
          },
          "role": {
            "description": "Structural role whose column changed after the reviewer confirmed it.",
            "enum": [
              "journal_key",
              "account",
              "amount",
              "effective_date",
              "period",
              "line_ordinal"
            ],
            "title": "Role",
            "type": "string"
          },
          "settled": {
            "description": "Columns the run settled for this role, in order; empty when it settled none.",
            "items": {
              "type": "string"
            },
            "title": "Settled",
            "type": "array"
          }
        },
        "required": [
          "role",
          "confirmed",
          "settled"
        ],
        "title": "MappingChange",
        "type": "object"
      },
      "MappingConfirmationRequired": {
        "additionalProperties": false,
        "properties": {
          "changes": {
            "description": "Each confirmed role the run settled differently; empty for a model-confirmed package.",
            "items": {
              "$ref": "#/components/schemas/MappingChange"
            },
            "title": "Changes",
            "type": "array"
          },
          "proposed": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StructureProposal"
              },
              {
                "type": "null"
              }
            ],
            "description": "The mapping the run settled, offered for confirmation; null when it settled no complete one."
          },
          "reason": {
            "description": "Why parsing waits: a model rather than a person confirmed the package, or the run settled columns other than the ones a person confirmed.",
            "enum": [
              "model_confirmed_package",
              "mapping_changed"
            ],
            "title": "Reason",
            "type": "string"
          }
        },
        "required": [
          "reason"
        ],
        "title": "MappingConfirmationRequired",
        "type": "object"
      },
      "MediaComponentInfo": {
        "additionalProperties": false,
        "description": "A recording: timeline facts, no paths — ask about it with qa-file.",
        "properties": {
          "duration_ms": {
            "description": "Length of the recording in milliseconds.",
            "title": "Duration Ms",
            "type": "integer"
          },
          "kind": {
            "const": "media",
            "default": "media",
            "title": "Kind",
            "type": "string"
          },
          "modality": {
            "description": "Whether the recording is `audio` or `video`.",
            "enum": [
              "audio",
              "video"
            ],
            "title": "Modality",
            "type": "string"
          },
          "speaker_count": {
            "description": "Distinct speakers detected in the recording.",
            "title": "Speaker Count",
            "type": "integer"
          },
          "summary": {
            "default": "",
            "description": "What the recording covers, as summarized at ingestion.",
            "title": "Summary",
            "type": "string"
          }
        },
        "required": [
          "modality",
          "duration_ms",
          "speaker_count"
        ],
        "title": "MediaComponentInfo",
        "type": "object"
      },
      "MediaFrameRef": {
        "additionalProperties": false,
        "description": "One sampled video frame referenced from a timeline segment.",
        "properties": {
          "path": {
            "description": "Path of this frame inside the media artifact, relative to the timeline.",
            "title": "Path",
            "type": "string"
          },
          "timestamp_ms": {
            "description": "Frame timestamp in integer milliseconds from the start of the recording.",
            "title": "Timestamp Ms",
            "type": "integer"
          }
        },
        "required": [
          "timestamp_ms",
          "path"
        ],
        "title": "MediaFrameRef",
        "type": "object"
      },
      "MediaSilenceSegment": {
        "additionalProperties": false,
        "description": "A stretch with no transcribed speech, kept so the timeline has no holes.",
        "properties": {
          "end_ms": {
            "description": "Exclusive end of this silence stretch, in integer milliseconds.",
            "title": "End Ms",
            "type": "integer"
          },
          "frames": {
            "description": "Sampled video frames that fall inside this silent stretch. Empty for audio and when none were sampled.",
            "items": {
              "$ref": "#/components/schemas/MediaFrameRef"
            },
            "title": "Frames",
            "type": "array"
          },
          "kind": {
            "const": "silence",
            "default": "silence",
            "title": "Kind",
            "type": "string"
          },
          "speaker": {
            "description": "Always null on a silence segment so every segment shares a speaker slot.",
            "title": "Speaker",
            "type": "null"
          },
          "start_ms": {
            "description": "Inclusive start of this silence stretch, in integer milliseconds.",
            "title": "Start Ms",
            "type": "integer"
          },
          "transcript": {
            "const": "",
            "default": "",
            "description": "Always empty on a silence segment so every segment shares a transcript slot.",
            "title": "Transcript",
            "type": "string"
          }
        },
        "required": [
          "start_ms",
          "end_ms"
        ],
        "title": "MediaSilenceSegment",
        "type": "object"
      },
      "MediaSpeaker": {
        "additionalProperties": false,
        "description": "A diarizer speaker cluster on a parse transcript.",
        "properties": {
          "id": {
            "description": "Diarizer cluster id for this speaker, for example SPEAKER_00.",
            "title": "Id",
            "type": "string"
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Mapped display name when a caller assigned one. Null when only the cluster id is known.",
            "title": "Label"
          }
        },
        "required": [
          "id"
        ],
        "title": "MediaSpeaker",
        "type": "object"
      },
      "MediaSpeechSegment": {
        "additionalProperties": false,
        "description": "A stretch of one speaker talking on the parse transcript.",
        "properties": {
          "end_ms": {
            "description": "Exclusive end of this speech stretch, in integer milliseconds.",
            "title": "End Ms",
            "type": "integer"
          },
          "frames": {
            "description": "Sampled video frames that fall inside this stretch. Empty for audio and when none were sampled.",
            "items": {
              "$ref": "#/components/schemas/MediaFrameRef"
            },
            "title": "Frames",
            "type": "array"
          },
          "kind": {
            "const": "speech",
            "default": "speech",
            "title": "Kind",
            "type": "string"
          },
          "speaker": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Diarizer cluster id that spoke this stretch. Null only when diarization produced no turns.",
            "title": "Speaker"
          },
          "start_ms": {
            "description": "Inclusive start of this speech stretch, in integer milliseconds.",
            "title": "Start Ms",
            "type": "integer"
          },
          "transcript": {
            "description": "Recognized speech text for this stretch. The field name is transcript, not text.",
            "title": "Transcript",
            "type": "string"
          }
        },
        "required": [
          "start_ms",
          "end_ms",
          "speaker",
          "transcript"
        ],
        "title": "MediaSpeechSegment",
        "type": "object"
      },
      "MediaTimeline": {
        "additionalProperties": false,
        "description": "Seekable MediaTimeline JSON carried inline on an audio or video parse.",
        "properties": {
          "duration_ms": {
            "description": "Probed duration of the recording in integer milliseconds.",
            "title": "Duration Ms",
            "type": "integer"
          },
          "modality": {
            "description": "Whether the source was an audio file or a video file.",
            "enum": [
              "audio",
              "video"
            ],
            "title": "Modality",
            "type": "string"
          },
          "peaks": {
            "description": "Windowed RMS envelope over the full recording, 0..1 inclusive. Empty means measurement unavailable.",
            "items": {
              "type": "number"
            },
            "title": "Peaks",
            "type": "array"
          },
          "schema_version": {
            "description": "Timeline schema version. Current parses emit version 2.",
            "title": "Schema Version",
            "type": "integer"
          },
          "segments": {
            "description": "Ordered gapless run of speech and silence covering the whole recording.",
            "items": {
              "discriminator": {
                "mapping": {
                  "silence": "#/components/schemas/MediaSilenceSegment",
                  "speech": "#/components/schemas/MediaSpeechSegment"
                },
                "propertyName": "kind"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/MediaSpeechSegment"
                },
                {
                  "$ref": "#/components/schemas/MediaSilenceSegment"
                }
              ]
            },
            "title": "Segments",
            "type": "array"
          },
          "speakers": {
            "description": "Diarizer clusters discovered in the recording. Labels stay null unless a caller mapped them.",
            "items": {
              "$ref": "#/components/schemas/MediaSpeaker"
            },
            "title": "Speakers",
            "type": "array"
          }
        },
        "required": [
          "schema_version",
          "modality",
          "duration_ms"
        ],
        "title": "MediaTimeline",
        "type": "object"
      },
      "ModelTokenUsage": {
        "description": "One model's share of a run's LLM spend.\n\nPer model rather than per run alone because a single run legitimately spends\non several: a search agent's own turns, the vision engine that cracked a\nscan, the sub-model an RLM read used. They are priced differently, so a\ntotal without this breakdown cannot be turned into money.",
        "properties": {
          "cached_input_tokens": {
            "default": 0,
            "description": "The share of input_tokens served from the provider's prompt cache — billed at a reduced rate, so pricing needs it separated out rather than subtracted.",
            "title": "Cached Input Tokens",
            "type": "integer"
          },
          "input_tokens": {
            "default": 0,
            "description": "Prompt tokens sent to this model, cached ones included.",
            "title": "Input Tokens",
            "type": "integer"
          },
          "model": {
            "description": "Model identifier as the provider reported it, or as the caller asked for it.",
            "title": "Model",
            "type": "string"
          },
          "output_tokens": {
            "default": 0,
            "description": "Completion tokens this model generated.",
            "title": "Output Tokens",
            "type": "integer"
          },
          "requests": {
            "default": 0,
            "description": "Observed provider attempts, including explicitly recorded failures.",
            "title": "Requests",
            "type": "integer"
          }
        },
        "required": [
          "model"
        ],
        "title": "ModelTokenUsage",
        "type": "object"
      },
      "MoneyCell": {
        "additionalProperties": false,
        "description": "An amount with its original ISO currency — never converted or normalized (D9).\n\nMixed-currency comparison and aggregation are unsupported in this version:\nresults assume the compared records share a currency and always show it.",
        "properties": {
          "amount": {
            "description": "Decimal-as-string, 2 decimal places.",
            "title": "Amount",
            "type": "string"
          },
          "currency": {
            "description": "ISO 4217 code as stated by the source.",
            "title": "Currency",
            "type": "string"
          },
          "currency_source": {
            "default": "stated",
            "description": "How the currency was arrived at: 'stated' when the source named it, 'assumed' when the workspace's default currency disambiguated a symbol the source left open (e.g. a bare '$'). Never a conversion — the amount is always the figure the document showed.",
            "enum": [
              "stated",
              "assumed"
            ],
            "title": "Currency Source",
            "type": "string"
          },
          "kind": {
            "const": "money",
            "default": "money",
            "title": "Kind",
            "type": "string"
          }
        },
        "required": [
          "amount",
          "currency"
        ],
        "title": "MoneyCell",
        "type": "object"
      },
      "NativeFileMetadata": {
        "additionalProperties": false,
        "properties": {
          "properties": {
            "description": "Format-native properties discovered inside the uploaded file.",
            "items": {
              "$ref": "#/components/schemas/NativeMetadataProperty"
            },
            "title": "Properties",
            "type": "array"
          },
          "source_modified_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Filesystem modification time reported by the uploading client; informational, not audit evidence.",
            "title": "Source Modified At"
          }
        },
        "title": "NativeFileMetadata",
        "type": "object"
      },
      "NativeMetadataProperty": {
        "additionalProperties": false,
        "properties": {
          "key": {
            "description": "Format-qualified property name, such as pdf.creator or image.exif.Model.",
            "title": "Key",
            "type": "string"
          },
          "value": {
            "description": "Property value preserved as text from the source container.",
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "key",
          "value"
        ],
        "title": "NativeMetadataProperty",
        "type": "object"
      },
      "NoulAnswer": {
        "additionalProperties": false,
        "properties": {
          "noul": {
            "description": "Probability, from 0 to 1, that the statement is true.",
            "title": "Noul",
            "type": "number"
          },
          "type": {
            "const": "noul",
            "default": "noul",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "noul"
        ],
        "title": "NoulAnswer",
        "type": "object"
      },
      "NoulCriteria": {
        "additionalProperties": false,
        "properties": {
          "false": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What makes the statement false, in the caller's words.",
            "title": "False"
          },
          "true": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "What makes the statement true, in the caller's words.",
            "title": "True"
          }
        },
        "title": "NoulCriteria",
        "type": "object"
      },
      "NoulQuestion": {
        "additionalProperties": false,
        "description": "A yes/no question. Its answer is the probability that the statement is true.",
        "properties": {
          "criteria": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NoulCriteria"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional descriptions of the true and false outcomes."
          },
          "instructions": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question to decide. Needs instructions or at least one criterion.",
            "title": "Instructions"
          },
          "type": {
            "const": "noul",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "type"
        ],
        "title": "NoulQuestion",
        "type": "object"
      },
      "NumberCell": {
        "additionalProperties": false,
        "properties": {
          "kind": {
            "const": "number",
            "default": "number",
            "title": "Kind",
            "type": "string"
          },
          "number": {
            "description": "Decimal-as-string.",
            "title": "Number",
            "type": "string"
          }
        },
        "required": [
          "number"
        ],
        "title": "NumberCell",
        "type": "object"
      },
      "OcrBoundingBox": {
        "additionalProperties": false,
        "description": "Normalized top-left OCR geometry for one page.",
        "properties": {
          "height": {
            "description": "Normalized height of the box, 0-1 of the page height.",
            "title": "Height",
            "type": "number"
          },
          "left": {
            "description": "Normalized left edge of the box, 0-1 from the page left.",
            "title": "Left",
            "type": "number"
          },
          "original_page": {
            "description": "1-based page in the original file, before conversion.",
            "title": "Original Page",
            "type": "integer"
          },
          "page": {
            "description": "1-based page this box was measured on after any conversion.",
            "title": "Page",
            "type": "integer"
          },
          "top": {
            "description": "Normalized top edge of the box, 0-1 from the page top.",
            "title": "Top",
            "type": "number"
          },
          "width": {
            "description": "Normalized width of the box, 0-1 of the page width.",
            "title": "Width",
            "type": "number"
          }
        },
        "required": [
          "left",
          "top",
          "width",
          "height",
          "page",
          "original_page"
        ],
        "title": "OcrBoundingBox",
        "type": "object"
      },
      "OcrElement": {
        "additionalProperties": false,
        "description": "One inline OCR word or line.",
        "properties": {
          "bbox": {
            "$ref": "#/components/schemas/OcrBoundingBox",
            "description": "Normalized page geometry for this word or line."
          },
          "chunk_index": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Index into document.chunks when this element was assigned to a chunk.",
            "title": "Chunk Index"
          },
          "confidence": {
            "description": "OCR engine confidence for this element, 0-1.",
            "title": "Confidence",
            "type": "number"
          },
          "rotation": {
            "default": 0,
            "description": "Clockwise rotation of the element in degrees.",
            "title": "Rotation",
            "type": "integer"
          },
          "text": {
            "description": "Recognized text of this word or line.",
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text",
          "bbox",
          "confidence"
        ],
        "title": "OcrElement",
        "type": "object"
      },
      "OpenQuestionWire": {
        "additionalProperties": false,
        "description": "One thing the data could not settle, asked exactly once.",
        "properties": {
          "candidates": {
            "description": "The alternatives the data leaves open, where it narrows them at all.",
            "items": {
              "type": "string"
            },
            "title": "Candidates",
            "type": "array"
          },
          "evidence": {
            "description": "What the census measured about the choice, one line per measurement.",
            "items": {
              "type": "string"
            },
            "title": "Evidence",
            "type": "array"
          },
          "exclusive_group": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Questions sharing this group take distinct columns; null when the question stands alone.",
            "title": "Exclusive Group"
          },
          "id": {
            "description": "A stable id within this report, assigned after a deterministic sort.",
            "title": "Id",
            "type": "string"
          },
          "question": {
            "description": "The question, phrased so it can be answered from the package itself.",
            "title": "Question",
            "type": "string"
          },
          "slot": {
            "description": "The binding slot or convention this question is about.",
            "title": "Slot",
            "type": "string"
          }
        },
        "required": [
          "id",
          "slot",
          "question",
          "candidates",
          "evidence"
        ],
        "title": "OpenQuestionWire",
        "type": "object"
      },
      "PackageCandidate": {
        "additionalProperties": false,
        "properties": {
          "confidence": {
            "description": "Model confidence, not measured readiness.",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "title": "Confidence",
            "type": "string"
          },
          "key_warning": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the proposed journal key or line ordinal cannot identify every line, by the catalog's null counts, after the repair still named it. The selected run searches the measured population for another key.",
            "title": "Key Warning"
          },
          "primary_source_id": {
            "description": "Catalog handle of the proposed posting population.",
            "title": "Primary Source Id",
            "type": "string"
          },
          "rationale": {
            "description": "Short reasons for proposing this package.",
            "items": {
              "type": "string"
            },
            "maxItems": 4,
            "title": "Rationale",
            "type": "array"
          },
          "structure": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProposedStructure"
              },
              {
                "type": "null"
              }
            ],
            "description": "Column interpretation awaiting measurement; absent for native SAP contracts."
          },
          "supporting_source_ids": {
            "description": "Catalog handles of supporting references.",
            "items": {
              "type": "string"
            },
            "title": "Supporting Source Ids",
            "type": "array"
          },
          "trial_balance_source_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Supporting reference nominated as trial balance.",
            "title": "Trial Balance Source Id"
          },
          "user_master_source_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Supporting reference nominated as user master.",
            "title": "User Master Source Id"
          },
          "warnings": {
            "description": "Limitations to resolve during review.",
            "items": {
              "type": "string"
            },
            "maxItems": 8,
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "primary_source_id",
          "confidence"
        ],
        "title": "PackageCandidate",
        "type": "object"
      },
      "PackageTieBreak": {
        "additionalProperties": false,
        "properties": {
          "choice": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Primary handle the model chose among competing high-confidence packages; null when its answer named none of them.",
            "title": "Choice"
          },
          "confidence": {
            "description": "Model confidence in the choice, not measured readiness.",
            "enum": [
              "high",
              "medium",
              "low"
            ],
            "title": "Confidence",
            "type": "string"
          },
          "rationale": {
            "description": "Short reasons for the choice.",
            "items": {
              "type": "string"
            },
            "maxItems": 4,
            "title": "Rationale",
            "type": "array"
          }
        },
        "required": [
          "choice",
          "confidence"
        ],
        "title": "PackageTieBreak",
        "type": "object"
      },
      "PageRange": {
        "additionalProperties": false,
        "description": "One-based inclusive page range shared by document operations.",
        "properties": {
          "end": {
            "description": "Last page of the range, 1-based and inclusive.",
            "minimum": 1.0,
            "title": "End",
            "type": "integer"
          },
          "start": {
            "description": "First page of the range, 1-based and inclusive.",
            "minimum": 1.0,
            "title": "Start",
            "type": "integer"
          }
        },
        "required": [
          "start",
          "end"
        ],
        "title": "PageRange",
        "type": "object"
      },
      "PageRegion": {
        "additionalProperties": false,
        "description": "A region on a 1-based page. A bbox is a 4-point polygon.",
        "properties": {
          "kind": {
            "const": "page_region",
            "default": "page_region",
            "title": "Kind",
            "type": "string"
          },
          "page": {
            "description": "1-based page number this region sits on.",
            "minimum": 1.0,
            "title": "Page",
            "type": "integer"
          },
          "polygons": {
            "description": "One or more polygons in normalized 0-1 coordinates, used to draw overlays.",
            "items": {
              "items": {
                "maxItems": 2,
                "minItems": 2,
                "prefixItems": [
                  {
                    "type": "number"
                  },
                  {
                    "type": "number"
                  }
                ],
                "type": "array"
              },
              "minItems": 3,
              "type": "array"
            },
            "title": "Polygons",
            "type": "array"
          }
        },
        "required": [
          "page"
        ],
        "title": "PageRegion",
        "type": "object"
      },
      "PageSelection": {
        "additionalProperties": false,
        "description": "One or more one-based inclusive page ranges.",
        "properties": {
          "ranges": {
            "description": "One-based inclusive page ranges to include. At least one range is required.",
            "items": {
              "$ref": "#/components/schemas/PageRange"
            },
            "maxItems": 200,
            "minItems": 1,
            "title": "Ranges",
            "type": "array"
          }
        },
        "required": [
          "ranges"
        ],
        "title": "PageSelection",
        "type": "object"
      },
      "Page_AccessLabelCatalogEntry_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/AccessLabelCatalogEntry"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[AccessLabelCatalogEntry]",
        "type": "object"
      },
      "Page_DomainSummary_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/DomainSummary"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[DomainSummary]",
        "type": "object"
      },
      "Page_ExtractionSchemaSummary_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/ExtractionSchemaSummary"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[ExtractionSchemaSummary]",
        "type": "object"
      },
      "Page_ExtractionSchema_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/ExtractionSchema"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[ExtractionSchema]",
        "type": "object"
      },
      "Page_FileVersion_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/FileVersion"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[FileVersion]",
        "type": "object"
      },
      "Page_Job_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/Job"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[Job]",
        "type": "object"
      },
      "Page_Tenant_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/Tenant"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[Tenant]",
        "type": "object"
      },
      "Page_Workspace_": {
        "additionalProperties": false,
        "properties": {
          "items": {
            "description": "This page's rows, in the list's order.",
            "items": {
              "$ref": "#/components/schemas/Workspace"
            },
            "title": "Items",
            "type": "array"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque; null means the last page.",
            "title": "Next Cursor"
          },
          "total_count": {
            "description": "Exact, and filtered by the caller's access predicate.",
            "title": "Total Count",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total_count"
        ],
        "title": "Page[Workspace]",
        "type": "object"
      },
      "PairedAmount": {
        "additionalProperties": false,
        "properties": {
          "credit": {
            "description": "Credit column on every primary member.",
            "minLength": 1,
            "title": "Credit",
            "type": "string"
          },
          "debit": {
            "description": "Debit column on every primary member.",
            "minLength": 1,
            "title": "Debit",
            "type": "string"
          },
          "kind": {
            "const": "paired",
            "description": "Separate debit and credit columns.",
            "title": "Kind",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "debit",
          "credit"
        ],
        "title": "PairedAmount",
        "type": "object"
      },
      "ParseCapProfileWire": {
        "additionalProperties": false,
        "description": "Aggregate journal complexity for one stop reason; contains no business values.",
        "properties": {
          "groups_max": {
            "description": "Largest group count per journal.",
            "title": "Groups Max",
            "type": "integer"
          },
          "groups_median": {
            "description": "Median account and direction group count per journal.",
            "title": "Groups Median",
            "type": "number"
          },
          "groups_p95": {
            "description": "Group count at the ninety-fifth percentile.",
            "title": "Groups P95",
            "type": "number"
          },
          "journals": {
            "description": "Distinct journals stopped for this reason.",
            "title": "Journals",
            "type": "integer"
          },
          "lines_max": {
            "description": "Largest represented posting count per journal.",
            "title": "Lines Max",
            "type": "integer"
          },
          "lines_median": {
            "description": "Median represented posting count per journal.",
            "title": "Lines Median",
            "type": "number"
          },
          "lines_p95": {
            "description": "Posting count at the ninety-fifth percentile.",
            "title": "Lines P95",
            "type": "number"
          }
        },
        "required": [
          "journals",
          "groups_median",
          "groups_p95",
          "groups_max",
          "lines_median",
          "lines_p95",
          "lines_max"
        ],
        "title": "ParseCapProfileWire",
        "type": "object"
      },
      "ParseChunk": {
        "additionalProperties": false,
        "description": "One RAG-oriented chunk produced when ``chunking.strategy`` is not ``none``.",
        "properties": {
          "content": {
            "description": "Chunk text sized for retrieval, not the full document rendering.",
            "title": "Content",
            "type": "string"
          },
          "id": {
            "description": "Stable id of this chunk within the parsed document.",
            "title": "Id",
            "type": "string"
          },
          "location": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "json_pointer": "#/components/schemas/JsonPointer",
                    "page_region": "#/components/schemas/PageRegion",
                    "row_range": "#/components/schemas/RowRange",
                    "sheet_range": "#/components/schemas/SheetRange",
                    "table_region": "#/components/schemas/TableRegion",
                    "text_span": "#/components/schemas/TextSpan"
                  },
                  "propertyName": "kind"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/PageRegion"
                  },
                  {
                    "$ref": "#/components/schemas/SheetRange"
                  },
                  {
                    "$ref": "#/components/schemas/TextSpan"
                  },
                  {
                    "$ref": "#/components/schemas/RowRange"
                  },
                  {
                    "$ref": "#/components/schemas/TableRegion"
                  },
                  {
                    "$ref": "#/components/schemas/JsonPointer"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this chunk sits in the source. Null when chunking did not emit geometry.",
            "title": "Location"
          }
        },
        "required": [
          "id",
          "content"
        ],
        "title": "ParseChunk",
        "type": "object"
      },
      "ParseChunkingOptions": {
        "additionalProperties": false,
        "properties": {
          "strategy": {
            "default": "none",
            "description": "How result.document.chunks is built. none leaves the list empty; page and section produce RAG-sized pieces with locations.",
            "enum": [
              "none",
              "page",
              "section"
            ],
            "title": "Strategy",
            "type": "string"
          }
        },
        "title": "ParseChunkingOptions",
        "type": "object"
      },
      "ParseDiagramsOptions": {
        "additionalProperties": false,
        "properties": {
          "mode": {
            "default": "omit",
            "description": "Whether flowchart-like figures stay as images or are rewritten as Mermaid fences.",
            "enum": [
              "omit",
              "mermaid"
            ],
            "title": "Mode",
            "type": "string"
          }
        },
        "title": "ParseDiagramsOptions",
        "type": "object"
      },
      "ParseDocument": {
        "additionalProperties": false,
        "description": "The parsed document payload under ``ParseResult.document``.",
        "properties": {
          "blocks": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ParsedBlock"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Layout blocks with locations when requested in output.formats; null if omitted.",
            "title": "Blocks"
          },
          "chunks": {
            "description": "RAG chunks when chunking.strategy is not none; otherwise empty.",
            "items": {
              "$ref": "#/components/schemas/ParseChunk"
            },
            "title": "Chunks",
            "type": "array"
          },
          "content_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authenticated streaming URL for complete content when markdown contains only a bounded preview.",
            "title": "Content Url"
          },
          "has_signature": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "True when a signature was detected on any parsed page; the blocks of type signature say where. False only when every parsed page was checked and none was found. Absent or null when signature detection did not run on every parsed page.",
            "title": "Has Signature"
          },
          "markdown": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Markdown rendering when requested in output.formats; null if that format was omitted.",
            "title": "Markdown"
          },
          "ocr": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseOcrData"
              },
              {
                "type": "null"
              }
            ],
            "description": "Word- and line-level OCR geometry when output.return_ocr_data is true."
          },
          "page_count": {
            "description": "Number of pages (or equivalent sheets) in the parsed source.",
            "title": "Page Count",
            "type": "integer"
          },
          "spreadsheet": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSpreadsheet"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workbook sidecars such as per-sheet cell maps. Null for non-spreadsheet sources."
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Plaintext rendering when requested in output.formats; headings and images stripped.",
            "title": "Text"
          }
        },
        "required": [
          "page_count"
        ],
        "title": "ParseDocument",
        "type": "object"
      },
      "ParseEngine": {
        "description": "Stable public identity for the parse engine that produced a result.",
        "enum": [
          "native_ocr",
          "document_ocr",
          "layout_ocr"
        ],
        "title": "ParseEngine",
        "type": "string"
      },
      "ParseFidelityDisclosure": {
        "additionalProperties": false,
        "description": "An oversized parse used a bounded fidelity mode without dropping extracted text.",
        "properties": {
          "code": {
            "const": "parse_fidelity",
            "title": "Code",
            "type": "string"
          },
          "mode": {
            "description": "Rendering or layout adjustment applied to fit the processing memory budget.",
            "enum": [
              "reduced_resolution",
              "reduced_layout"
            ],
            "title": "Mode",
            "type": "string"
          },
          "pages": {
            "description": "Exact 1-based source pages affected when physical pages are available; empty when the bounded format has no reliable physical-page map.",
            "items": {
              "minimum": 1.0,
              "type": "integer"
            },
            "title": "Pages",
            "type": "array"
          }
        },
        "required": [
          "code",
          "mode",
          "pages"
        ],
        "title": "ParseFidelityDisclosure",
        "type": "object"
      },
      "ParseFiguresOptions": {
        "additionalProperties": false,
        "properties": {
          "mode": {
            "default": "include",
            "description": "Whether figure regions are dropped, kept as crops, or kept with a generated caption. Defaults to include. describe adds one vision caption call per figure.",
            "enum": [
              "omit",
              "include",
              "describe"
            ],
            "title": "Mode",
            "type": "string"
          }
        },
        "title": "ParseFiguresOptions",
        "type": "object"
      },
      "ParseJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "parse",
            "default": "parse",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ndi_service__app__platform_api__results__ParseResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "ParseJob",
        "type": "object"
      },
      "ParseOcrData": {
        "additionalProperties": false,
        "description": "Optional inline OCR geometry requested by the caller.",
        "properties": {
          "lines": {
            "description": "Line-level OCR elements when output.return_ocr_data is true.",
            "items": {
              "$ref": "#/components/schemas/OcrElement"
            },
            "title": "Lines",
            "type": "array"
          },
          "words": {
            "description": "Word-level OCR elements when output.return_ocr_data is true.",
            "items": {
              "$ref": "#/components/schemas/OcrElement"
            },
            "title": "Words",
            "type": "array"
          }
        },
        "title": "ParseOcrData",
        "type": "object"
      },
      "ParseOcrOptions": {
        "additionalProperties": false,
        "properties": {
          "languages": {
            "description": "Optional BCP-47 language hints for OCR. Empty lets the engine detect language.",
            "items": {
              "type": "string"
            },
            "title": "Languages",
            "type": "array"
          },
          "mode": {
            "default": "auto",
            "description": "When to run OCR. auto runs only if the file needs it; force always runs; disabled never runs. ocr_applied on the result says whether OCR actually ran.",
            "enum": [
              "auto",
              "force",
              "disabled"
            ],
            "title": "Mode",
            "type": "string"
          }
        },
        "title": "ParseOcrOptions",
        "type": "object"
      },
      "ParseOutputOptions": {
        "additionalProperties": false,
        "properties": {
          "formats": {
            "description": "Which renderings to populate on result.document. Omitted formats are null. Default is markdown plus layout blocks; text is a stripped plaintext rendering.",
            "items": {
              "enum": [
                "markdown",
                "text",
                "blocks"
              ],
              "type": "string"
            },
            "title": "Formats",
            "type": "array"
          },
          "include_images": {
            "default": false,
            "description": "When true, figure blocks include a crop URL for PDF and raster uploads. A figure that cannot be cropped keeps image_url null; the job still succeeds.",
            "title": "Include Images",
            "type": "boolean"
          },
          "include_page_markers": {
            "default": true,
            "description": "Insert `--- Page N ---` headers between PDF pages in markdown and text. On by default. Page chunking and the canonical Parse dependency retain these headers internally when this is false, then strip them from the returned document.",
            "title": "Include Page Markers",
            "type": "boolean"
          },
          "return_ocr_data": {
            "default": false,
            "description": "When true, attach word- and line-level OCR geometry on result.document.ocr.",
            "title": "Return Ocr Data",
            "type": "boolean"
          },
          "table_format": {
            "default": "html",
            "description": "How tables are written inside markdown and text. Layout blocks keep their own table structure.",
            "enum": [
              "html",
              "markdown"
            ],
            "title": "Table Format",
            "type": "string"
          }
        },
        "title": "ParseOutputOptions",
        "type": "object"
      },
      "ParsePreviewContent": {
        "additionalProperties": false,
        "properties": {
          "generation": {
            "description": "Provider invocation that produced this preview.",
            "title": "Generation",
            "type": "string"
          },
          "index": {
            "description": "Original page number or selected sheet position.",
            "title": "Index",
            "type": "integer"
          },
          "label": {
            "description": "Page label or original sheet name.",
            "title": "Label",
            "type": "string"
          },
          "markdown": {
            "description": "Checked preview text before document-wide finalization.",
            "title": "Markdown",
            "type": "string"
          },
          "ready_at": {
            "description": "Server time at which the unit became ready.",
            "format": "date-time",
            "title": "Ready At",
            "type": "string"
          },
          "truncated": {
            "description": "This unit exceeded the preview budget; complete content is in the final result.",
            "title": "Truncated",
            "type": "boolean"
          }
        },
        "required": [
          "generation",
          "index",
          "label",
          "markdown",
          "truncated",
          "ready_at"
        ],
        "title": "ParsePreviewContent",
        "type": "object"
      },
      "ParsePreviewSnapshot": {
        "additionalProperties": false,
        "properties": {
          "all_ready_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server publication time when every requested preview was saved; document finalization can follow.",
            "title": "All Ready At"
          },
          "first_ready_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Server publication time of the first nonempty preview; null when not measured or unavailable.",
            "title": "First Ready At"
          },
          "generation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Provider invocation whose preview is current.",
            "title": "Generation"
          },
          "job_id": {
            "description": "Parse job being observed.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "anyOf": [
              {
                "enum": [
                  "page",
                  "sheet",
                  "section",
                  "segment"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Natural unit of this preview.",
            "title": "Kind"
          },
          "more": {
            "default": false,
            "description": "The bounded preview omits further units; the final result remains complete.",
            "title": "More",
            "type": "boolean"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Authoritative lifecycle state of the owning job."
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Number of requested units when known.",
            "title": "Total"
          },
          "units": {
            "description": "Ready units in original document order.",
            "items": {
              "$ref": "#/components/schemas/ParsePreviewUnit"
            },
            "title": "Units",
            "type": "array"
          }
        },
        "required": [
          "job_id",
          "status"
        ],
        "title": "ParsePreviewSnapshot",
        "type": "object"
      },
      "ParsePreviewUnit": {
        "additionalProperties": false,
        "properties": {
          "content_url": {
            "description": "Authenticated URL for this bounded preview unit.",
            "title": "Content Url",
            "type": "string"
          },
          "index": {
            "description": "Original page number or selected sheet position.",
            "title": "Index",
            "type": "integer"
          },
          "revision": {
            "description": "Opaque immutable revision used to replace a prior preview.",
            "title": "Revision",
            "type": "string"
          }
        },
        "required": [
          "index",
          "revision",
          "content_url"
        ],
        "title": "ParsePreviewUnit",
        "type": "object"
      },
      "ParseRequest": {
        "additionalProperties": false,
        "description": "Body for canonical ``POST /v1/parse`` (and the hidden legacy alias).\n\n``page_ranges`` is the canonical one-based inclusive selector. Legacy\n``page_range`` / ``pages`` remain accepted on the wire during rollout.\n\n``password`` is write-only: it is never stored in ``ndi_job.input`` or\nreturned in any response. The service stores an AES-GCM-encrypted copy in\n``ndi_job_secret`` for the unlock activity to consume once, then empties it.",
        "properties": {
          "chunking": {
            "$ref": "#/components/schemas/ParseChunkingOptions",
            "description": "Optional RAG chunking of the parsed document."
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "diagrams": {
            "$ref": "#/components/schemas/ParseDiagramsOptions",
            "description": "Whether diagram-like figures are rewritten as Mermaid."
          },
          "figures": {
            "$ref": "#/components/schemas/ParseFiguresOptions",
            "description": "How figure regions are kept or captioned."
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "ocr": {
            "$ref": "#/components/schemas/ParseOcrOptions",
            "description": "OCR on/off and language hints."
          },
          "output": {
            "$ref": "#/components/schemas/ParseOutputOptions",
            "description": "Which text renderings, table style, images, and OCR geometry to return."
          },
          "output_formats": {
            "anyOf": [
              {
                "items": {
                  "enum": [
                    "markdown",
                    "text",
                    "blocks"
                  ],
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy formats list. Prefer output.formats.",
            "title": "Output Formats"
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "page_range": {
            "anyOf": [
              {
                "maxItems": 2,
                "minItems": 2,
                "prefixItems": [
                  {
                    "type": "integer"
                  },
                  {
                    "type": "integer"
                  }
                ],
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy [start, end] pair. Prefer page_ranges.",
            "title": "Page Range"
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive page ranges to process. Omit to use the whole document.",
            "title": "Page Ranges"
          },
          "pages": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PageSelection"
              },
              {
                "type": "null"
              }
            ],
            "description": "Legacy page selector. Prefer page_ranges."
          },
          "parse_mode": {
            "default": "low",
            "description": "How much parsing effort to use: Low uses native OCR, Medium routes to the best parser, and High adds page verification and correction.",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Parse Mode",
            "type": "string"
          },
          "parser": {
            "anyOf": [
              {
                "enum": [
                  "native",
                  "datalab",
                  "nace_router"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Deprecated parse implementation override. Prefer parse_mode. Omit or null for native; 'datalab' and 'nace_router' remain accepted for compatibility.",
            "title": "Parser"
          },
          "password": {
            "anyOf": [
              {
                "maxLength": 1024,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional PDF password. Never stored in the job payload or returned in any response.",
            "title": "Password",
            "writeOnly": true
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "quality": {
            "default": "auto",
            "description": "Latency versus accuracy preference for this run.",
            "enum": [
              "auto",
              "fast",
              "accurate"
            ],
            "title": "Quality",
            "type": "string"
          },
          "source": {
            "description": "The document to read: a fresh upload, an HTTPS URL, a workspace file, or a prior parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          },
          "spreadsheet": {
            "$ref": "#/components/schemas/ParseSpreadsheetOptions",
            "description": "Workbook-only filters for sheets, hidden cells, and formulas."
          }
        },
        "required": [
          "source"
        ],
        "title": "ParseRequest",
        "type": "object"
      },
      "ParseRequestEcho": {
        "additionalProperties": true,
        "type": "object"
      },
      "ParseResultSource": {
        "additionalProperties": false,
        "description": "A prior Parse job whose parsed artifact can be reused by downstream methods.",
        "properties": {
          "job_id": {
            "description": "Succeeded parse job whose artifact should be reused.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "type": {
            "const": "parse_result",
            "default": "parse_result",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "job_id"
        ],
        "title": "ParseResultSource",
        "type": "object"
      },
      "ParseSettings": {
        "additionalProperties": false,
        "description": "Settings for the Parse that runs before Split, Classify, or Extract.\n\nA subset of the ``POST /v1/parse`` body with the same field names and nested\nmodels. Options that only shape the Parse response (``output``, ``chunking``)\nand options the runtime refuses (``quality``, ``ocr``) are not accepted here.\nA setting the file type cannot use is accepted and reported in the result's warnings.",
        "properties": {
          "diagrams": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseDiagramsOptions"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether flowchart-like figures are rewritten as Mermaid fences, as diagrams on Parse. Defaults to omit."
          },
          "figures": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettingsFigures"
              },
              {
                "type": "null"
              }
            ],
            "description": "How figure regions are kept in the Parse this operation reads. Omit to keep figures. Only figures.mode omit changes the Parse."
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive pages to read, as page_ranges on Parse. On an operation with its own page_ranges the two must agree. With a parse_result source it keeps only those pages of the reused Parse.",
            "title": "Page Ranges"
          },
          "parse_mode": {
            "anyOf": [
              {
                "enum": [
                  "high",
                  "medium",
                  "low"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Parsing effort for the Parse before this operation, as parse_mode on Parse. Omit to use the request's top-level parse_mode, which defaults to low.",
            "title": "Parse Mode"
          },
          "spreadsheet": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSpreadsheetOptions"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workbook controls, as spreadsheet on Parse. Applied to spreadsheet sources only."
          }
        },
        "title": "ParseSettings",
        "type": "object"
      },
      "ParseSettingsFigures": {
        "additionalProperties": false,
        "description": "How figure regions are kept in the Parse behind an operation.",
        "properties": {
          "mode": {
            "description": "omit drops figure regions from the Parse this operation reads. include and describe both keep them and are the default: the operation reads the same Parse for either.",
            "enum": [
              "omit",
              "include",
              "describe"
            ],
            "title": "Mode",
            "type": "string"
          }
        },
        "required": [
          "mode"
        ],
        "title": "ParseSettingsFigures",
        "type": "object"
      },
      "ParseSpreadsheet": {
        "additionalProperties": false,
        "description": "Spreadsheet-specific Parse artifacts.",
        "properties": {
          "sheets": {
            "description": "Per-sheet cell-map and complete-content URLs when the source was a workbook.",
            "items": {
              "$ref": "#/components/schemas/ParseSpreadsheetSheet"
            },
            "title": "Sheets",
            "type": "array"
          }
        },
        "title": "ParseSpreadsheet",
        "type": "object"
      },
      "ParseSpreadsheetOptions": {
        "additionalProperties": false,
        "description": "Workbook-specific Parse controls for spreadsheet sources.\n\nDefaults preserve the pre-control behavior: every sheet/row/column is\nincluded and formula *source text* is omitted (cached values still appear).",
        "properties": {
          "include_formulas": {
            "default": false,
            "description": "When true, include formula source text. Cached calculated values are always present.",
            "title": "Include Formulas",
            "type": "boolean"
          },
          "include_hidden_columns": {
            "default": true,
            "description": "When false, skip columns marked hidden.",
            "title": "Include Hidden Columns",
            "type": "boolean"
          },
          "include_hidden_rows": {
            "default": true,
            "description": "When false, skip rows marked hidden.",
            "title": "Include Hidden Rows",
            "type": "boolean"
          },
          "include_hidden_sheets": {
            "default": true,
            "description": "When false, skip sheets marked hidden in the workbook.",
            "title": "Include Hidden Sheets",
            "type": "boolean"
          },
          "sheets": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional sheet-name filter. When set, only listed sheets are parsed, in workbook order.",
            "title": "Sheets"
          }
        },
        "title": "ParseSpreadsheetOptions",
        "type": "object"
      },
      "ParseSpreadsheetSheet": {
        "additionalProperties": false,
        "description": "Downloadable artifacts for one rendered spreadsheet sheet.",
        "properties": {
          "cell_map_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authenticated job-scoped URL that maps rendered table axes to physical cells.",
            "title": "Cell Map Url"
          },
          "column_count": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Total source columns when a row browser is available.",
            "title": "Column Count"
          },
          "content_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authenticated streaming URL for complete sheet Markdown when document.markdown contains only a bounded preview.",
            "title": "Content Url"
          },
          "markdown_deferred": {
            "default": false,
            "description": "Full Markdown is generated on demand; content requests may return HTTP 202 while it is prepared.",
            "title": "Markdown Deferred",
            "type": "boolean"
          },
          "row_count": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Total source rows when a row browser is available.",
            "title": "Row Count"
          },
          "rows_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authenticated URL for bounded Parquet row pages; accepts start_row and limit.",
            "title": "Rows Url"
          },
          "sheet_name": {
            "description": "Workbook tab this cell map belongs to.",
            "title": "Sheet Name",
            "type": "string"
          },
          "source_sha256": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "SHA-256 of the immutable source used by row browsing and full Markdown export.",
            "title": "Source Sha256"
          }
        },
        "required": [
          "sheet_name"
        ],
        "title": "ParseSpreadsheetSheet",
        "type": "object"
      },
      "ParseSummaryWire": {
        "additionalProperties": false,
        "description": "What general-ledger parsing made of the package (§9).\n\nCounts, never rows: the mapping itself is a derived table the testing engine\njoins, and a report that carried it would be a download. The five outcome\ncounts add up to ``journals_total`` by construction — every journal is\nrepresented exactly once, and a hub, an unbalanced entry or a capped one is a\nnamed outcome rather than a missing row.\n\nThe parquet URLs are withheld for the reason the receipts' SQL is: they name\ninternal storage keys, and a caller has no route that reads them.",
        "properties": {
          "attempted_candidates": {
            "default": 0,
            "description": "Candidate journals actually evaluated by the parser.",
            "title": "Attempted Candidates",
            "type": "integer"
          },
          "basis": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The amount basis the parse netted on, or null when it was skipped.",
            "title": "Basis"
          },
          "candidate_coverage": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Attempted candidates divided by all candidates, or null when none exist.",
            "title": "Candidate Coverage"
          },
          "candidates": {
            "description": "Journals holding enough account/debit-credit groups to be worth splitting.",
            "title": "Candidates",
            "type": "integer"
          },
          "candidates_capped": {
            "description": "Whether the population cap cut the candidate set.",
            "title": "Candidates Capped",
            "type": "boolean"
          },
          "cap_profiles": {
            "additionalProperties": {
              "$ref": "#/components/schemas/ParseCapProfileWire"
            },
            "description": "Group and posting count distributions by exact stop reason.",
            "title": "Cap Profiles",
            "type": "object"
          },
          "cap_reason_counts": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Distinct journals per exact parse stop reason, including the population cap.",
            "title": "Cap Reason Counts",
            "type": "object"
          },
          "capped": {
            "description": "Journals left whole because a bound stopped the parse rather than a reading.",
            "title": "Capped",
            "type": "integer"
          },
          "confirmation_required": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MappingConfirmationRequired"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when parsing waits for a person to confirm the ledger mapping, with the mapping the run settled."
          },
          "decimals": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The minor-unit scale the parse netted at.",
            "title": "Decimals"
          },
          "duration_ms": {
            "description": "Milliseconds the parsing pass spent on this package.",
            "title": "Duration Ms",
            "type": "integer"
          },
          "hub": {
            "description": "Journals where one control account offsets every other — correctly left whole.",
            "title": "Hub",
            "type": "integer"
          },
          "identity": {
            "description": "Journals that were never bundles, so each is its own sub-journal.",
            "title": "Identity",
            "type": "integer"
          },
          "journals_total": {
            "description": "Journals found in the ledger, on the accepted journal key.",
            "title": "Journals Total",
            "type": "integer"
          },
          "parse_run_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identity of this parse: the package, the version, and its parameters.",
            "title": "Parse Run Id"
          },
          "parsed": {
            "description": "Journals split into more than one balanced sub-journal.",
            "title": "Parsed",
            "type": "integer"
          },
          "per_bucket": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Sub-journals per confidence bucket, keyed '1'–'4': 1 proven, 2 reserved, 3 ambiguous and available on demand, 4 refused as a split.",
            "title": "Per Bucket",
            "type": "object"
          },
          "population_capped": {
            "description": "Candidates the cap excluded; published whole rather than dropped.",
            "title": "Population Capped",
            "type": "integer"
          },
          "population_capped_share": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Population-capped candidates divided by all candidates, or null when none exist.",
            "title": "Population Capped Share"
          },
          "resource_failure": {
            "anyOf": [
              {
                "enum": [
                  "spill_capacity",
                  "memory"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exhausted engine resource that prevented parsing.",
            "title": "Resource Failure"
          },
          "skipped_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why no mapping was produced, when none was. A skipped parse is a recorded answer: the rest of the report stands and the tables are simply absent.",
            "title": "Skipped Reason"
          },
          "solver_cap_hits": {
            "description": "Of those, the ones the solver itself refused.",
            "title": "Solver Cap Hits",
            "type": "integer"
          },
          "sub_journals_total": {
            "description": "Sub-journals published across the whole ledger.",
            "title": "Sub Journals Total",
            "type": "integer"
          },
          "tables": {
            "description": "The published tables, empty when the pass was skipped.",
            "items": {
              "$ref": "#/components/schemas/DerivedTableWire"
            },
            "title": "Tables",
            "type": "array"
          },
          "unbalanced": {
            "description": "Journals whose own lines do not net to zero.",
            "title": "Unbalanced",
            "type": "integer"
          }
        },
        "required": [
          "journals_total",
          "candidates",
          "candidates_capped",
          "population_capped",
          "parsed",
          "identity",
          "hub",
          "unbalanced",
          "capped",
          "solver_cap_hits",
          "sub_journals_total",
          "per_bucket",
          "basis",
          "decimals",
          "parse_run_id",
          "duration_ms",
          "skipped_reason",
          "tables"
        ],
        "title": "ParseSummaryWire",
        "type": "object"
      },
      "ParseVendorProvenanceDisclosure": {
        "additionalProperties": false,
        "description": "The file was processed by a vendor other than the router's first choice.\n\nThe parse result is valid. The vendor name is published so a caller can\naccount for differing output quality or formatting between vendors.",
        "properties": {
          "code": {
            "const": "parse_vendor_provenance",
            "title": "Code",
            "type": "string"
          },
          "engine": {
            "$ref": "#/components/schemas/ParseEngine",
            "description": "Stable engine identity that produced the parse without exposing the underlying supplier."
          },
          "fallback_depth": {
            "description": "Number of earlier engines that failed before this engine produced the result.",
            "minimum": 0.0,
            "title": "Fallback Depth",
            "type": "integer"
          }
        },
        "required": [
          "code",
          "engine",
          "fallback_depth"
        ],
        "title": "ParseVendorProvenanceDisclosure",
        "type": "object"
      },
      "ParsedBlock": {
        "additionalProperties": false,
        "description": "One structural unit of a parsed document.",
        "properties": {
          "confidence": {
            "anyOf": [
              {
                "maximum": 1.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Probability, from 0 to 1, that this block's text matches the page, from the OCR review when it ran. Null when the block was not reviewed, or its text changed after review.",
            "title": "Confidence"
          },
          "content": {
            "description": "Text or caption carried by this block.",
            "title": "Content",
            "type": "string"
          },
          "id": {
            "description": "Stable id of this layout block within the parsed document.",
            "title": "Id",
            "type": "string"
          },
          "image_anchor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SheetRange"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where a picture is anchored on a worksheet; not the location of its OCR data cells."
          },
          "image_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Crop URL when output.include_images is true and this block is a figure region.",
            "title": "Image Url"
          },
          "location": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "json_pointer": "#/components/schemas/JsonPointer",
                    "page_region": "#/components/schemas/PageRegion",
                    "row_range": "#/components/schemas/RowRange",
                    "sheet_range": "#/components/schemas/SheetRange",
                    "table_region": "#/components/schemas/TableRegion",
                    "text_span": "#/components/schemas/TextSpan"
                  },
                  "propertyName": "kind"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/PageRegion"
                  },
                  {
                    "$ref": "#/components/schemas/SheetRange"
                  },
                  {
                    "$ref": "#/components/schemas/TextSpan"
                  },
                  {
                    "$ref": "#/components/schemas/RowRange"
                  },
                  {
                    "$ref": "#/components/schemas/TableRegion"
                  },
                  {
                    "$ref": "#/components/schemas/JsonPointer"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this block sits in the source. Null when the parser did not emit geometry.",
            "title": "Location"
          },
          "markdown_span": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TextSpan"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unicode code-point span in document.markdown, exclusive end. Separate from native source location."
          },
          "sheet_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Owning worksheet, including appendix blocks without a cell range. Null for non-spreadsheet blocks.",
            "title": "Sheet Name"
          },
          "source_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identity of the embedded image or attachment within this document.",
            "title": "Source Id"
          },
          "source_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Embedded source display name, including nested attachment paths.",
            "title": "Source Name"
          },
          "table_row_offset": {
            "default": 0,
            "description": "Offset of body rows in the sheet cell map; repeated table header still addresses row index zero.",
            "minimum": 0.0,
            "title": "Table Row Offset",
            "type": "integer"
          },
          "type": {
            "description": "Layout role of the block, for example heading, paragraph, table, figure, or signature. A signature block marks where a signature appears; its content is the placeholder [SIGNATURE].",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "id",
          "type",
          "content"
        ],
        "title": "ParsedBlock",
        "type": "object"
      },
      "PathPrefixQueryScope": {
        "additionalProperties": false,
        "description": "The question ran against one folder subtree.",
        "properties": {
          "prefix": {
            "maxLength": 1024,
            "minLength": 1,
            "title": "Prefix",
            "type": "string"
          },
          "type": {
            "const": "path_prefix",
            "default": "path_prefix",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "prefix"
        ],
        "title": "PathPrefixQueryScope",
        "type": "object"
      },
      "PathPrefixSelection": {
        "additionalProperties": false,
        "description": "A folder. ``\"\"`` or ``\"/\"`` means the whole workspace.",
        "properties": {
          "path_prefix": {
            "default": "",
            "maxLength": 1024,
            "title": "Path Prefix",
            "type": "string"
          },
          "stale_only": {
            "default": false,
            "description": "Re-ingest only files whose observed and ingested hashes diverged.",
            "title": "Stale Only",
            "type": "boolean"
          },
          "type": {
            "const": "path_prefix",
            "default": "path_prefix",
            "title": "Type",
            "type": "string"
          }
        },
        "title": "PathPrefixSelection",
        "type": "object"
      },
      "PlaygroundQuota": {
        "additionalProperties": false,
        "description": "How many anonymous tries remain in the current window.",
        "properties": {
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "remaining": {
            "title": "Remaining",
            "type": "integer"
          },
          "reset_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reset At"
          }
        },
        "required": [
          "remaining",
          "limit"
        ],
        "title": "PlaygroundQuota",
        "type": "object"
      },
      "PopulationCandidateWire": {
        "additionalProperties": false,
        "properties": {
          "attempts": {
            "description": "Bounded aggregate candidate measurement and rejection explanations.",
            "items": {
              "$ref": "#/components/schemas/KeyAttempt"
            },
            "title": "Attempts",
            "type": "array"
          },
          "balanced_share": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Measured journal balance share; not a selection rule.",
            "title": "Balanced Share"
          },
          "basis": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Basis measured by the accepted key proof.",
            "title": "Basis"
          },
          "classification": {
            "default": "candidate",
            "description": "How complete-population evidence relates this source to the settled primary.",
            "enum": [
              "primary",
              "duplicate_projection",
              "supporting_reversal",
              "candidate"
            ],
            "title": "Classification",
            "type": "string"
          },
          "classification_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Bounded explanation of the automatic classification, where one was proven.",
            "title": "Classification Reason"
          },
          "journal_key": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Accepted complete-population identity, or unknown.",
            "title": "Journal Key"
          },
          "label": {
            "description": "The composer's candidate label; use the existing role-slot review flow.",
            "title": "Label",
            "type": "string"
          },
          "member_count": {
            "description": "Complete member count, including members beyond the listing bound.",
            "title": "Member Count",
            "type": "integer"
          },
          "paths": {
            "description": "Bounded member paths in this package scope.",
            "items": {
              "type": "string"
            },
            "title": "Paths",
            "type": "array"
          },
          "rows": {
            "description": "Census row count across all members.",
            "title": "Rows",
            "type": "integer"
          },
          "selected": {
            "description": "Whether this exact member set fills the journal-lines slot.",
            "title": "Selected",
            "type": "boolean"
          },
          "tables": {
            "description": "Bounded physical member names.",
            "items": {
              "type": "string"
            },
            "title": "Tables",
            "type": "array"
          },
          "unresolved_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this population has no accepted identity.",
            "title": "Unresolved Reason"
          }
        },
        "required": [
          "label",
          "tables",
          "paths",
          "member_count",
          "rows",
          "selected"
        ],
        "title": "PopulationCandidateWire",
        "type": "object"
      },
      "PreparationSummaryWire": {
        "additionalProperties": false,
        "description": "Bounded status of one configured reusable JET relationship.",
        "properties": {
          "bucket_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Published bucket count when preparation is ready.",
            "title": "Bucket Count"
          },
          "duration_ms": {
            "default": 0,
            "description": "Milliseconds spent loading or preparing this relationship.",
            "title": "Duration Ms",
            "type": "integer"
          },
          "left_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Rows published for the left side when ready.",
            "title": "Left Rows"
          },
          "name": {
            "description": "Stable configured relationship name.",
            "title": "Name",
            "type": "string"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Bounded reason when the relationship is not ready.",
            "title": "Reason"
          },
          "reused": {
            "default": false,
            "description": "Whether an existing complete generation was reused.",
            "title": "Reused",
            "type": "boolean"
          },
          "right_rows": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Rows published for the right side when ready.",
            "title": "Right Rows"
          },
          "size_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Combined byte size of both published sides when ready.",
            "title": "Size Bytes"
          },
          "status": {
            "description": "Whether a complete reusable generation was published.",
            "enum": [
              "ready",
              "unavailable",
              "failed"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "name",
          "status"
        ],
        "title": "PreparationSummaryWire",
        "type": "object"
      },
      "PreparedIdentityNormalizationConfig": {
        "additionalProperties": false,
        "description": "Compare a VARCHAR key exactly as stored.",
        "properties": {
          "kind": {
            "const": "identity",
            "default": "identity",
            "description": "Keep the stored text unchanged.",
            "title": "Kind",
            "type": "string"
          }
        },
        "title": "PreparedIdentityNormalizationConfig",
        "type": "object"
      },
      "PreparedKeyConfig": {
        "additionalProperties": false,
        "description": "One ordered equality component of a prepared relationship.",
        "properties": {
          "left_column": {
            "description": "Column on the left table.",
            "minLength": 1,
            "title": "Left Column",
            "type": "string"
          },
          "left_normalization": {
            "description": "Reviewed normalization applied to the left column.",
            "discriminator": {
              "mapping": {
                "identity": "#/components/schemas/PreparedIdentityNormalizationConfig",
                "left_pad": "#/components/schemas/PreparedLeftPadNormalizationConfig"
              },
              "propertyName": "kind"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/PreparedIdentityNormalizationConfig"
              },
              {
                "$ref": "#/components/schemas/PreparedLeftPadNormalizationConfig"
              }
            ],
            "title": "Left Normalization"
          },
          "right_column": {
            "description": "Column on the right table.",
            "minLength": 1,
            "title": "Right Column",
            "type": "string"
          },
          "right_normalization": {
            "description": "Reviewed normalization applied to the right column.",
            "discriminator": {
              "mapping": {
                "identity": "#/components/schemas/PreparedIdentityNormalizationConfig",
                "left_pad": "#/components/schemas/PreparedLeftPadNormalizationConfig"
              },
              "propertyName": "kind"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/PreparedIdentityNormalizationConfig"
              },
              {
                "$ref": "#/components/schemas/PreparedLeftPadNormalizationConfig"
              }
            ],
            "title": "Right Normalization"
          }
        },
        "required": [
          "left_column",
          "right_column"
        ],
        "title": "PreparedKeyConfig",
        "type": "object"
      },
      "PreparedLeftPadNormalizationConfig": {
        "additionalProperties": false,
        "description": "Apply the declared single-character left padding before comparison.",
        "properties": {
          "fill": {
            "description": "Single character used for padding.",
            "maxLength": 1,
            "minLength": 1,
            "title": "Fill",
            "type": "string"
          },
          "kind": {
            "const": "left_pad",
            "default": "left_pad",
            "description": "Left-pad the stored text to a fixed width.",
            "title": "Kind",
            "type": "string"
          },
          "width": {
            "description": "Width of the normalized key.",
            "exclusiveMinimum": 0.0,
            "maximum": 1024.0,
            "title": "Width",
            "type": "integer"
          }
        },
        "required": [
          "width",
          "fill"
        ],
        "title": "PreparedLeftPadNormalizationConfig",
        "type": "object"
      },
      "PreparedRelationshipConfig": {
        "additionalProperties": false,
        "description": "One reviewed large-table relationship ledger understanding should prepare.",
        "properties": {
          "bucket_count": {
            "description": "Number of hash buckets materialized on each side.",
            "exclusiveMinimum": 0.0,
            "maximum": 1024.0,
            "title": "Bucket Count",
            "type": "integer"
          },
          "keys": {
            "description": "Ordered equality key components.",
            "items": {
              "$ref": "#/components/schemas/PreparedKeyConfig"
            },
            "maxItems": 8,
            "minItems": 1,
            "title": "Keys",
            "type": "array"
          },
          "left": {
            "$ref": "#/components/schemas/PreparedTableSelectionConfig",
            "description": "Workspace table used as the left side."
          },
          "name": {
            "description": "Stable name for the prepared relationship.",
            "maxLength": 100,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          },
          "right": {
            "$ref": "#/components/schemas/PreparedTableSelectionConfig",
            "description": "Workspace table used as the right side."
          }
        },
        "required": [
          "name",
          "left",
          "right",
          "keys",
          "bucket_count"
        ],
        "title": "PreparedRelationshipConfig",
        "type": "object"
      },
      "PreparedTableSelectionConfig": {
        "additionalProperties": false,
        "description": "One logical source table selected by its stable workspace coordinate.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Worksheet or component when the path has more than one table.",
            "title": "Component"
          },
          "path": {
            "description": "Workspace path or published dataset root.",
            "minLength": 1,
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "PreparedTableSelectionConfig",
        "type": "object"
      },
      "ProcedureReadinessWire": {
        "additionalProperties": false,
        "description": "Readiness for one procedure, never a blanket permission to run JET.",
        "properties": {
          "reasons": {
            "description": "Limits or missing evidence for this procedure.",
            "items": {
              "type": "string"
            },
            "title": "Reasons",
            "type": "array"
          },
          "status": {
            "description": "Whether this procedure's inputs are available.",
            "enum": [
              "ready",
              "limited",
              "unavailable",
              "unknown"
            ],
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "status"
        ],
        "title": "ProcedureReadinessWire",
        "type": "object"
      },
      "ProposedStructure": {
        "additionalProperties": false,
        "properties": {
          "account": {
            "description": "Exact physical columns forming the ordered account identity. Use one complete account-code column, or the evidenced account segments and namespace qualifiers needed to distinguish accounts. May share qualifiers with journal_key; remains a nomination awaiting measured validation.",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "title": "Account",
            "type": "array"
          },
          "amount": {
            "description": "Proposed amount columns and their interpretation.",
            "discriminator": {
              "mapping": {
                "paired": "#/components/schemas/PairedAmount",
                "signed": "#/components/schemas/SignedAmount"
              },
              "propertyName": "kind"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/PairedAmount"
              },
              {
                "$ref": "#/components/schemas/SignedAmount"
              }
            ],
            "title": "Amount"
          },
          "effective_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Proposed typed posting date column.",
            "title": "Effective Date"
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Proposed entity qualifier, retained for reviewer context.",
            "title": "Entity"
          },
          "journal_key": {
            "description": "Ordered journal identity to measure.",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "title": "Journal Key",
            "type": "array"
          },
          "line_ordinal": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Proposed numeric line ordinal column.",
            "title": "Line Ordinal"
          },
          "period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Proposed fiscal period column.",
            "title": "Period"
          }
        },
        "required": [
          "journal_key",
          "account",
          "amount"
        ],
        "title": "ProposedStructure",
        "type": "object"
      },
      "PutTenantRequest": {
        "additionalProperties": false,
        "description": "Create a tenant, or update the one with this ``external_ref``. Omitted fields stay as they are.",
        "properties": {
          "data_retention": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GranularRetention"
              },
              {
                "type": "null"
              }
            ],
            "description": "How the tenant's document operations retain data: short or zero_retention. Omit it when creating to inherit your own setting, or when updating to leave it unchanged."
          },
          "disabled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "True disables the tenant (its requests answer tenant_disabled); false re-enables it.",
            "title": "Disabled"
          },
          "display_name": {
            "anyOf": [
              {
                "description": "Human-readable name of the tenant.",
                "maxLength": 128,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Display Name"
          },
          "limits": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TenantLimitsRequest"
              },
              {
                "type": "null"
              }
            ],
            "description": "Limits to set on the tenant."
          },
          "workspace_storage_limit_bytes": {
            "anyOf": [
              {
                "exclusiveMinimum": 0.0,
                "maximum": 9.223372036854776e+18,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Allowance for current source-file bytes across this tenant’s managed workspaces. Omit to preserve the allowance; null removes it. Enforcement requires WORKSPACE_STORAGE_LIMITS_ENABLED.",
            "title": "Workspace Storage Limit Bytes"
          }
        },
        "title": "PutTenantRequest",
        "type": "object"
      },
      "QaFileRequest": {
        "additionalProperties": false,
        "description": "Request body for ``qa-file``.\n\n``path`` names an **uploaded source file** — the same addressing as\n``file-metadata``; a workspace-internal derivative path is refused with\n``invalid_request``. ``component`` scopes the question to one public\ncomponent by name (a pdf section or a workbook tab — the names\n``file-metadata`` lists). For a PDF it may also name one of the figures\n``file-metadata`` lists (``figure p3-1``: vision over that picture alone)\nor a page (``page 3``: vision over the whole rendered page).",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Component"
          },
          "include_citations": {
            "default": true,
            "title": "Include Citations",
            "type": "boolean"
          },
          "output_schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A JSON Schema (Draft 2020-12, object root, local non-recursive `$ref` only, no `pattern`, `patternProperties` or `unevaluated*`) the answer must follow. When set, the agent writes `answer` as JSON text conforming to it, the run checks that and asks the agent to correct a mismatch, and the result carries the parsed value in `structured_answer`. A field the source does not state comes back null, whatever type the schema gives it. Explanation goes to `reasoning` where the result has one, and evidences are unchanged. If the answer still misses the schema, the run succeeds with `answer` as written and `structured_answer` null. Omit for a prose answer.",
            "title": "Output Schema"
          },
          "path": {
            "description": "The uploaded file's full path relative to the workspace root, exactly as it was uploaded and as listings and search results print it — e.g. `evidence/doc-7f83/contract.pdf`. Not a bare file name (a file's `file_name`), a folder, a file id, or a path that starts with the workspace id.",
            "maxLength": 1024,
            "minLength": 1,
            "title": "Path",
            "type": "string"
          },
          "query": {
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          }
        },
        "required": [
          "path",
          "query"
        ],
        "title": "QaFileRequest",
        "type": "object"
      },
      "QaFileResponse": {
        "additionalProperties": false,
        "description": "Response body for ``qa-file``.\n\n``engine`` reports what answered: ``recursive_llm`` for prose, ``vision``\nfor an image, and ``agent`` when the file has several parts and a QA agent\nworked across them. Citations always name the uploaded file, never\nanything internal.\n\n``job_id`` is the durable job row created for this run; poll or retrieve\nit via ``GET /v1/jobs/{job_id}`` to get the stored answer after the fact.\n\nBilling: a question answered by ``recursive_llm`` or ``vision`` (one piece\nof content: a text section, transcript, image, page or figure, including\na ``component``-scoped question) is not billed. An ``agent`` answer bills\none unit per agent step.\n\n``unavailable`` is always empty since table files moved to ``query-tables``\n(which reports unqueryable selections there); the field is retained for\nwire compatibility.",
        "properties": {
          "answer": {
            "title": "Answer",
            "type": "string"
          },
          "citations": {
            "items": {
              "$ref": "#/components/schemas/Evidence"
            },
            "title": "Citations",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The engine's self-graded confidence in the answer — how well the file content it read supports it, on the shared six-level scale (certain / very_high / high / medium / low / speculative). Null when the engine could not grade (a timeout's partial answer, a legacy run)."
          },
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "engine": {
            "enum": [
              "recursive_llm",
              "vision",
              "agent"
            ],
            "title": "Engine",
            "type": "string"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "structured_answer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JsonValue"
              },
              {
                "type": "null"
              }
            ],
            "description": "`answer` parsed as JSON, set only when the request carried `output_schema` and the answer validates against it; a field the source does not state is null whatever type the schema gives it. Null on every run without a schema, and on a run whose answer still missed the schema after its corrections, where `answer` holds the text as written."
          },
          "timed_out": {
            "default": false,
            "title": "Timed Out",
            "type": "boolean"
          },
          "unavailable": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/UnavailableTable"
            },
            "title": "Unavailable",
            "type": "array"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "answer",
          "citations",
          "engine"
        ],
        "title": "QaFileResponse",
        "type": "object"
      },
      "QaFileResult": {
        "additionalProperties": false,
        "description": "One qa-file run, stored whole so the answer can be reopened.\n\nEvery field past ``exhausted`` arrived with job-backed history; rows written\nbefore it carry only the two receipt fields and still validate, so nothing\nneeds backfilling. A reopened run answers the same question over the same\nscope: ``scope_path`` and ``scope_component`` are what the caller asked\nabout, not where the answer came from.",
        "properties": {
          "answer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The prose the run returned. Null only on a pre-history row.",
            "title": "Answer"
          },
          "citations": {
            "items": {
              "$ref": "#/components/schemas/Evidence"
            },
            "title": "Citations",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The engine's self-graded confidence; None when it could not grade."
          },
          "engine": {
            "anyOf": [
              {
                "enum": [
                  "recursive_llm",
                  "vision",
                  "agent"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Engine"
          },
          "exhausted": {
            "default": false,
            "description": "The agent's step budget ran out before it completed an answer. A successful run, not a failure.",
            "title": "Exhausted",
            "type": "boolean"
          },
          "result_type": {
            "const": "qa_file",
            "default": "qa_file",
            "title": "Result Type",
            "type": "string"
          },
          "scope_component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The component (tab / section) the ask was narrowed to.",
            "title": "Scope Component"
          },
          "scope_path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The uploaded file the question was asked about.",
            "title": "Scope Path"
          },
          "steps_used": {
            "default": 0,
            "title": "Steps Used",
            "type": "integer"
          },
          "structured_answer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JsonValue"
              },
              {
                "type": "null"
              }
            ],
            "description": "`answer` parsed as JSON, set only when the request carried `output_schema` and the answer validates against it; a field the source does not state is null whatever type the schema gives it. Null on every run without a schema, and on a run whose answer still missed the schema after its corrections, where `answer` holds the text as written."
          },
          "timed_out": {
            "default": false,
            "description": "A guard fired before the engine answered. The body holds the partial-answer wording, not a failure.",
            "title": "Timed Out",
            "type": "boolean"
          },
          "unavailable": {
            "items": {
              "$ref": "#/components/schemas/UnavailableTable"
            },
            "title": "Unavailable",
            "type": "array"
          }
        },
        "title": "QaFileResult",
        "type": "object"
      },
      "QaJob": {
        "additionalProperties": false,
        "description": "One turn of a ``qa`` conversation: the automatic search agent's job, answered or asking back.",
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "automatic_agent",
            "default": "automatic_agent",
            "description": "The automatic search agent, which answers every QA turn.",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AutomaticAgentResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "QaJob",
        "type": "object"
      },
      "QaRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /workspaces/{workspace_id}/qa`` — one turn of a question-answering conversation.\n\nEach turn runs the automatic search agent alone: no router, no fact\npipeline and no opening search. The agent finds what the turn needs itself,\nin the light of the conversation so far, then reads and computes until it can\nanswer. No model, effort or tool-surface field: the service resolves the\nconfiguration.",
        "properties": {
          "allow_clarification": {
            "default": true,
            "description": "Let the agent ask instead of guessing when a question is genuinely ambiguous and the reading materially changes the answer. Such a turn's result carries the questions in `clarification_questions` with `answer` null; reply in the same conversation with `clarification_answers` or a rephrased query. A turn that sends `clarification_answers` never asks again. On by default; off means the agent always answers with its best reading, stated in the answer.",
            "title": "Allow Clarification",
            "type": "boolean"
          },
          "clarification_answers": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ClarificationAnswer"
                },
                "maxItems": 2,
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Answers to the clarifying questions this conversation's last turn asked, one per question, in order. Send them with that turn's `session_id` and its `query`; the agent then answers that query with the answers applied.",
            "title": "Clarification Answers"
          },
          "context": {
            "anyOf": [
              {
                "maxLength": 20000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Free-form background for the model — the engagement, the entity, what the caller already knows. It informs the answer; it does not widen or narrow which files the caller may see.",
            "title": "Context"
          },
          "output_schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A JSON Schema (Draft 2020-12, object root, local non-recursive `$ref` only, no `pattern`, `patternProperties` or `unevaluated*`) the answer must follow. When set, the agent writes `answer` as JSON text conforming to it, the run checks that and asks the agent to correct a mismatch, and the result carries the parsed value in `structured_answer`. A field the source does not state comes back null, whatever type the schema gives it. Explanation goes to `reasoning` where the result has one, and evidences are unchanged. If the answer still misses the schema, the run succeeds with `answer` as written and `structured_answer` null. Omit for a prose answer. Applies only to the turn that sends it: to keep structured answers across a conversation, send it on every turn, including a reply to clarifying questions. A turn that asks clarifying questions returns them with `structured_answer` null.",
            "title": "Output Schema"
          },
          "path_prefix": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Put every uploaded file under one folder subtree, workspace-relative, in the run's scope; `paths`, where the body takes it, adds more files. Omit both for the whole workspace.",
            "title": "Path Prefix"
          },
          "paths": {
            "anyOf": [
              {
                "items": {
                  "maxLength": 1024,
                  "minLength": 1,
                  "type": "string"
                },
                "minItems": 1,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Scope the conversation to exactly these uploaded files. Every tool the agent runs sees only these files and the content ingested from them. Each entry names an uploaded source file (never a folder — scope folders with path_prefix; the two add up). Unknown or inaccessible paths are refused up front.",
            "title": "Paths"
          },
          "query": {
            "description": "What to answer, in the caller's own words. Stripped before its length is checked; a blank query is refused rather than run.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          },
          "session_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Continue a conversation: the `session_id` echoed on an earlier turn's result. With the same folder/file scope and access grants the agent resumes the conversation, so a follow-up can lean on what was already asked and answered; a changed scope or grants starts a fresh conversation and returns a new `session_id`. Omit to start one. Only the API key that started it may continue it; a conversation whose turn is still running returns 409 session_busy.",
            "title": "Session Id"
          }
        },
        "required": [
          "query"
        ],
        "title": "QaRequest",
        "type": "object"
      },
      "QaTableResultFile": {
        "additionalProperties": false,
        "description": "A Parquet result this run retained, addressable in the caller's workspace.\n\nThe canonical ``s3://`` / ``file://`` location is deliberately absent: it is\nkept privately alongside the stored result (``StoredQaTablesResult``), and\nevery read mints a fresh, expiring pair of URLs from it. A stored URL would\nbe expired by the time anyone reopened the run.",
        "properties": {
          "download_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Minted on read; null when the artifact is gone.",
            "title": "Download Url"
          },
          "download_url_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Download Url Expires At"
          },
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "file_name": {
            "title": "File Name",
            "type": "string"
          },
          "format": {
            "const": "parquet",
            "default": "parquet",
            "title": "Format",
            "type": "string"
          },
          "grounding": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TableQueryGrounding"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exact source regions and bounded receipt data when capture-time provenance was available."
          },
          "handle": {
            "title": "Handle",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "preview_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Minted on read; null when the artifact is gone.",
            "title": "Preview Url"
          },
          "row_count": {
            "title": "Row Count",
            "type": "integer"
          },
          "source_paths": {
            "items": {
              "type": "string"
            },
            "title": "Source Paths",
            "type": "array"
          },
          "sql": {
            "title": "Sql",
            "type": "string"
          }
        },
        "required": [
          "file_id",
          "handle",
          "path",
          "file_name",
          "row_count",
          "sql"
        ],
        "title": "QaTableResultFile",
        "type": "object"
      },
      "QaTablesResult": {
        "additionalProperties": false,
        "description": "One query-tables run, stored whole so the answer can be reopened.\n\nAs with :class:`QaFileResult`, everything past ``exhausted`` arrived with\njob-backed history and is optional, so receipt-only rows still validate.\nBoth lanes land in this one shape: the SQL lane fills ``tables`` and\n``result_files``, the agent lane fills ``answer`` and ``citations`` only.",
        "properties": {
          "answer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The prose the run returned. Null only on a pre-history row.",
            "title": "Answer"
          },
          "citations": {
            "items": {
              "$ref": "#/components/schemas/Evidence"
            },
            "title": "Citations",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The engine's self-graded confidence; None when it could not grade."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The engine's own reported trouble on an otherwise 200 run.",
            "title": "Error"
          },
          "exhausted": {
            "default": false,
            "description": "The agent's step budget ran out before it completed an answer. A successful run, not a failure.",
            "title": "Exhausted",
            "type": "boolean"
          },
          "result_files": {
            "items": {
              "$ref": "#/components/schemas/QaTableResultFile"
            },
            "title": "Result Files",
            "type": "array"
          },
          "result_materialization_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Result Materialization Error"
          },
          "result_type": {
            "const": "qa_tables",
            "default": "qa_tables",
            "title": "Result Type",
            "type": "string"
          },
          "source_components": {
            "description": "The named tabs among those selections.",
            "items": {
              "type": "string"
            },
            "title": "Source Components",
            "type": "array"
          },
          "source_paths": {
            "description": "The table selections the question was asked over.",
            "items": {
              "type": "string"
            },
            "title": "Source Paths",
            "type": "array"
          },
          "steps_used": {
            "default": 0,
            "title": "Steps Used",
            "type": "integer"
          },
          "structured_answer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JsonValue"
              },
              {
                "type": "null"
              }
            ],
            "description": "`answer` parsed as JSON, set only when the request carried `output_schema` and the answer validates against it; a field the source does not state is null whatever type the schema gives it. Null on every run without a schema, and on a run whose answer still missed the schema after its corrections, where `answer` holds the text as written."
          },
          "tables": {
            "items": {
              "$ref": "#/components/schemas/QueryTablePreview"
            },
            "title": "Tables",
            "type": "array"
          },
          "timed_out": {
            "default": false,
            "title": "Timed Out",
            "type": "boolean"
          },
          "unavailable": {
            "items": {
              "$ref": "#/components/schemas/UnavailableTable"
            },
            "title": "Unavailable",
            "type": "array"
          }
        },
        "title": "QaTablesResult",
        "type": "object"
      },
      "QueryTableCitation": {
        "additionalProperties": false,
        "description": "Provenance for one generated TablesQA result file.",
        "properties": {
          "grounding": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TableQueryGrounding"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exact source regions and bounded receipt data when capture-time provenance was available."
          },
          "result_file": {
            "$ref": "#/components/schemas/QueryTableResultFile"
          },
          "source_paths": {
            "items": {
              "type": "string"
            },
            "title": "Source Paths",
            "type": "array"
          },
          "sql": {
            "title": "Sql",
            "type": "string"
          }
        },
        "required": [
          "result_file",
          "source_paths",
          "sql"
        ],
        "title": "QueryTableCitation",
        "type": "object"
      },
      "QueryTableColumn": {
        "additionalProperties": false,
        "description": "One public column in a retained result preview.",
        "properties": {
          "data_type": {
            "title": "Data Type",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "data_type"
        ],
        "title": "QueryTableColumn",
        "type": "object"
      },
      "QueryTablePreview": {
        "additionalProperties": false,
        "description": "One retained result table with a bounded inline preview.",
        "properties": {
          "columns": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/QueryTableColumn"
            },
            "maxItems": 50,
            "title": "Columns",
            "type": "array"
          },
          "handle": {
            "title": "Handle",
            "type": "string"
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Path"
          },
          "preview_truncated": {
            "default": false,
            "title": "Preview Truncated",
            "type": "boolean"
          },
          "row_count": {
            "title": "Row Count",
            "type": "integer"
          },
          "rows": {
            "default": [],
            "items": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "maxItems": 20,
            "title": "Rows",
            "type": "array"
          }
        },
        "required": [
          "handle",
          "row_count"
        ],
        "title": "QueryTablePreview",
        "type": "object"
      },
      "QueryTableResultFile": {
        "additionalProperties": false,
        "description": "A workspace-visible Parquet file retained from a TablesQA query.",
        "properties": {
          "download_url": {
            "title": "Download Url",
            "type": "string"
          },
          "download_url_expires_at": {
            "format": "date-time",
            "title": "Download Url Expires At",
            "type": "string"
          },
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "file_name": {
            "title": "File Name",
            "type": "string"
          },
          "format": {
            "const": "parquet",
            "title": "Format",
            "type": "string"
          },
          "handle": {
            "title": "Handle",
            "type": "string"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "preview_url": {
            "title": "Preview Url",
            "type": "string"
          },
          "row_count": {
            "title": "Row Count",
            "type": "integer"
          }
        },
        "required": [
          "file_id",
          "handle",
          "path",
          "file_name",
          "format",
          "row_count",
          "download_url",
          "preview_url",
          "download_url_expires_at"
        ],
        "title": "QueryTableResultFile",
        "type": "object"
      },
      "QueryTableSelection": {
        "additionalProperties": false,
        "description": "One selection row: a whole table file, or one tab of one workbook.\n\n``component`` is workbook-local vocabulary — the same strings\n``file-metadata`` publishes as ``component`` and ``qa-file`` accepts as\n``component=``, matched exact-name first, then the unambiguous sanitized\nalias. There is deliberately no cross-file component filter: the same tab\nname in two workbooks is two rows. Naming a component of a single-table\nupload (csv/jsonl/parquet — one table, no named parts) is refused rather\nthan silently ignored: the caller selected something that does not exist,\nand answering anyway would answer a different question.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "One tab of this workbook. Omit to select the whole file. Repeat the path in another row to select several tabs.",
            "title": "Component"
          },
          "path": {
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "QueryTableSelection",
        "type": "object"
      },
      "QueryTablesRequest": {
        "additionalProperties": false,
        "description": "Question over a bounded set of workspace-uploaded table selections.\n\nEvery row's ``path`` must name a **table file** — a spreadsheet (xlsx,\nxls, xlsm, xlsb, ods) or record file (csv, tsv, parquet, jsonl, ndjson,\njson); a document, media, or image path is refused with\n``invalid_request`` naming ``qa-file``. Every tab is\naskable whatever its ingestion produced — extracted rows, a rendered\nsheet, or both.",
        "properties": {
          "include_citations": {
            "default": true,
            "title": "Include Citations",
            "type": "boolean"
          },
          "output_schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "A JSON Schema (Draft 2020-12, object root, local non-recursive `$ref` only, no `pattern`, `patternProperties` or `unevaluated*`) the answer must follow. When set, the agent writes `answer` as JSON text conforming to it, the run checks that and asks the agent to correct a mismatch, and the result carries the parsed value in `structured_answer`. A field the source does not state comes back null, whatever type the schema gives it. Explanation goes to `reasoning` where the result has one, and evidences are unchanged. If the answer still misses the schema, the run succeeds with `answer` as written and `structured_answer` null. Omit for a prose answer.",
            "title": "Output Schema"
          },
          "paths": {
            "items": {
              "$ref": "#/components/schemas/QueryTableSelection"
            },
            "maxItems": 32,
            "minItems": 1,
            "title": "Paths",
            "type": "array"
          },
          "query": {
            "maxLength": 4096,
            "minLength": 1,
            "title": "Query",
            "type": "string"
          }
        },
        "required": [
          "paths",
          "query"
        ],
        "title": "QueryTablesRequest",
        "type": "object"
      },
      "QueryTablesResponse": {
        "additionalProperties": false,
        "description": "Answer, provenance, unavailable inputs, and retained result previews.\n\nTwo lanes fill this shape. An all-queryable selection runs the SQL engine\nand returns everything: ``tables`` previews, ``result_citations``, and SQL\nreceipts in ``citations``. A selection holding tabs without extracted rows\nruns a QA agent over the files' rendered sheets and row extractions\ntogether — the answer and quoted ``citations`` are filled, while\n``tables`` and ``result_citations`` stay empty (no SQL results exist to\nretain). ``unavailable`` reports selections with no usable content on\neither lane.\n\n``job_id`` is the durable job row created for this run; retrieve it via\n``GET /v1/jobs/{job_id}`` to inspect or replay the stored answer.",
        "properties": {
          "answer": {
            "title": "Answer",
            "type": "string"
          },
          "citations": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/Evidence"
            },
            "title": "Citations",
            "type": "array"
          },
          "confidence": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConfidenceLevel"
              },
              {
                "type": "null"
              }
            ],
            "description": "The engine's self-graded confidence in the answer — how well the queried tables support it, on the shared six-level scale (certain / very_high / high / medium / low / speculative). Null when the engine could not grade (a timeout's partial answer, a legacy run)."
          },
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Job Id"
          },
          "result_citations": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/QueryTableCitation"
            },
            "title": "Result Citations",
            "type": "array"
          },
          "result_materialization_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Result Materialization Error"
          },
          "structured_answer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JsonValue"
              },
              {
                "type": "null"
              }
            ],
            "description": "`answer` parsed as JSON, set only when the request carried `output_schema` and the answer validates against it; a field the source does not state is null whatever type the schema gives it. Null on every run without a schema, and on a run whose answer still missed the schema after its corrections, where `answer` holds the text as written."
          },
          "tables": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/QueryTablePreview"
            },
            "title": "Tables",
            "type": "array"
          },
          "timed_out": {
            "default": false,
            "title": "Timed Out",
            "type": "boolean"
          },
          "unavailable": {
            "default": [],
            "items": {
              "$ref": "#/components/schemas/UnavailableTable"
            },
            "title": "Unavailable",
            "type": "array"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "answer"
        ],
        "title": "QueryTablesResponse",
        "type": "object"
      },
      "ReadFileRequest": {
        "additionalProperties": false,
        "description": "Request body for ``read-file``.\n\n``path`` names an **uploaded source file** — the only namespace this tool\nserves. A workspace-internal derivative path is refused with\n``invalid_request`` naming the uploaded file that owns it.\n\n``component`` scopes the read to one public component by name — a\nspreadsheet tab or a pdf section, as listed by ``file-metadata``.\n\n``pages`` is 1-based and selects on the file's absolute page numbers;\nout-of-range pages are ignored (absent from ``pages_returned``). Selected\npages come back de-duplicated in document order, whatever order they were\nasked in. Spreadsheets have no pages — scope those with ``component``\ninstead.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "One tab or section to read, named as file-metadata lists it; omitted: the whole file.",
            "title": "Component"
          },
          "line_end": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last line to return, inclusive and 1-based like line_start. Omitted: the last line.",
            "title": "Line End"
          },
          "line_start": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "First line to return, 1-based, counted in the text this read would return without a line range (after component and page selection). Omitted: line 1.",
            "title": "Line Start"
          },
          "max_chars": {
            "default": 200000,
            "description": "Character budget for the returned text; past it `truncated` is true.",
            "maximum": 1000000.0,
            "minimum": 1.0,
            "title": "Max Chars",
            "type": "integer"
          },
          "pages": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "1-based page numbers to read; omitted: every page. Spreadsheets have no pages.",
            "title": "Pages"
          },
          "path": {
            "description": "The uploaded file's full path relative to the workspace root, exactly as it was uploaded and as listings and search results print it — e.g. `evidence/doc-7f83/contract.pdf`. Not a bare file name (a file's `file_name`), a folder, a file id, or a path that starts with the workspace id.",
            "maxLength": 1024,
            "minLength": 1,
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path"
        ],
        "title": "ReadFileRequest",
        "type": "object"
      },
      "ReadFileResponse": {
        "additionalProperties": false,
        "description": "Response body for ``read-file``.\n\nA file with several components (a spreadsheet's tabs, a pdf's sections)\nanswers with their text concatenated in the file's own order, each part\nprefixed by a one-line header naming the component. ``components_returned``\nlists what contributed to ``content``; ``components_omitted`` lists\ncomponents that were cut for size — the character budget ran out, or a\npart was too large to serve — or that have no text rendering at all (a\nquery-only tab; ask it with ``qa-file``) — so an absent component is\nalways visible, never a silently missing tab. Unnamed components (a\nrecording, a raw upload) are listed by kind. A table a PDF page holds\ncomes as rows — one ``| a | b |`` line each under a header that joins the\nstacked column headings — the way grep and hybrid-search print it.",
        "properties": {
          "components_omitted": {
            "items": {
              "type": "string"
            },
            "title": "Components Omitted",
            "type": "array"
          },
          "components_returned": {
            "items": {
              "type": "string"
            },
            "title": "Components Returned",
            "type": "array"
          },
          "content": {
            "title": "Content",
            "type": "string"
          },
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "file_id": {
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The external operation job; absent for commands inside a search job.",
            "title": "Job Id"
          },
          "line_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How many lines the whole selected text has, when the request named a line range; None otherwise.",
            "title": "Line Count"
          },
          "line_end": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Last line returned (inclusive) when the request named a line range; None otherwise or when line_start is past the end of the text.",
            "title": "Line End"
          },
          "line_start": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "First line returned (1-based) when the request named a line range; None otherwise.",
            "title": "Line Start"
          },
          "pages_returned": {
            "items": {
              "type": "integer"
            },
            "title": "Pages Returned",
            "type": "array"
          },
          "path": {
            "title": "Path",
            "type": "string"
          },
          "sql_tables": {
            "description": "The run-sql names of the tables holding the rows of the long tables printed in the returned PDF sections — count, total or rank those rows there rather than from the text. Empty for a spreadsheet or CSV tab: its table name is file-metadata's `table_name`.",
            "items": {
              "type": "string"
            },
            "title": "Sql Tables",
            "type": "array"
          },
          "table": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/GrepTable"
              },
              {
                "type": "null"
              }
            ],
            "description": "When a line range starts inside a table, below its header row: that table's lines, title and header, so the rows read with their column names."
          },
          "truncated": {
            "title": "Truncated",
            "type": "boolean"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "path",
          "file_id",
          "content",
          "pages_returned",
          "truncated",
          "components_returned",
          "components_omitted"
        ],
        "title": "ReadFileResponse",
        "type": "object"
      },
      "ReadFileResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "$ref": "#/components/schemas/ReadFileResponse",
            "description": "The operation response returned to the caller, retained with its job."
          },
          "result_type": {
            "const": "read_file",
            "default": "read_file",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "output"
        ],
        "title": "ReadFileResult",
        "type": "object"
      },
      "ReconcileRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /v1/workspaces/{workspace_id}/reconciliations``.\n\nReconciliation compares the customer-visible storage tree against the\nledger and records divergences there. The scan itself never changes stored\nbytes or derived representations. ``auto_ingest`` additionally chains\ningestion into the same request for the routine case.\n\nWhat ``reconcile`` can detect:\n\n* ``discovered`` — objects in storage that have no ledger row yet.\n* ``stale`` — ledger rows whose ``observed_hash`` no longer matches the\n  object in storage.\n* ``orphans`` — ledger rows whose object is gone from storage.\n\n``path_prefix`` scopes the scan; omit it (or pass ``\"\"``) to scan the\nwhole workspace.  ``auto_ingest`` queues an ingestion for everything the\nscan found, so the routine case is one call. Without it, ledger changes are\nstill recorded and the result tells you what diverged; no ingestion starts.",
        "properties": {
          "auto_ingest": {
            "default": false,
            "title": "Auto Ingest",
            "type": "boolean"
          },
          "path_prefix": {
            "anyOf": [
              {
                "maxLength": 1024,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Path Prefix"
          }
        },
        "title": "ReconcileRequest",
        "type": "object"
      },
      "ReconciliationJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "reconciliation",
            "default": "reconciliation",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReconciliationResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "ReconciliationJob",
        "type": "object"
      },
      "ReconciliationResult": {
        "additionalProperties": false,
        "description": "Reconciliation only ever *detects*; ingestion is what acts.",
        "properties": {
          "discovered": {
            "description": "In storage, absent from the ledger.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Discovered",
            "type": "array"
          },
          "files_scanned": {
            "title": "Files Scanned",
            "type": "integer"
          },
          "ingestion_job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when auto_ingest was requested.",
            "title": "Ingestion Job Id"
          },
          "marked_stale": {
            "description": "observed_hash != ingested_hash.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Marked Stale",
            "type": "array"
          },
          "orphans_removed": {
            "description": "In the ledger, absent from storage.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "Orphans Removed",
            "type": "array"
          },
          "result_type": {
            "const": "reconciliation",
            "default": "reconciliation",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "files_scanned"
        ],
        "title": "ReconciliationResult",
        "type": "object"
      },
      "RejectedCandidate": {
        "additionalProperties": false,
        "properties": {
          "conflicts": {
            "description": "Column-level role conflicts that made the proposed structure invalid.",
            "items": {
              "$ref": "#/components/schemas/StructureRoleConflict"
            },
            "title": "Conflicts",
            "type": "array"
          },
          "primary_source_id": {
            "description": "Primary handle returned by the model.",
            "title": "Primary Source Id",
            "type": "string"
          },
          "reason": {
            "description": "Why catalog validation refused the candidate.",
            "title": "Reason",
            "type": "string"
          }
        },
        "required": [
          "primary_source_id",
          "reason"
        ],
        "title": "RejectedCandidate",
        "type": "object"
      },
      "ReplaceFileJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "file_replace",
            "default": "file_replace",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReplaceFileResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "ReplaceFileJob",
        "type": "object"
      },
      "ReplaceFileResult": {
        "additionalProperties": false,
        "properties": {
          "file": {
            "$ref": "#/components/schemas/File"
          },
          "previous_version": {
            "title": "Previous Version",
            "type": "integer"
          },
          "result_type": {
            "const": "file_replace",
            "default": "file_replace",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "file",
          "previous_version"
        ],
        "title": "ReplaceFileResult",
        "type": "object"
      },
      "ReplaceWorkspaceSharesRequest": {
        "additionalProperties": false,
        "description": "The complete explicit share set that should remain after this request.",
        "properties": {
          "user_ids": {
            "description": "Complete set of console users who should have explicit access; send an empty list to remove every share.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "User Ids",
            "type": "array"
          }
        },
        "title": "ReplaceWorkspaceSharesRequest",
        "type": "object"
      },
      "RepresentationState": {
        "additionalProperties": false,
        "description": "Whether each representation is current for a file.\n\nAnswers \"is this file actually searchable right now\", which\n``ingestion_status`` alone cannot: a file can be ingested while its graph\ngeneration is still building.",
        "properties": {
          "knowledge_graph": {
            "default": false,
            "title": "Knowledge Graph",
            "type": "boolean"
          },
          "organized_files": {
            "default": false,
            "title": "Organized Files",
            "type": "boolean"
          },
          "search_index": {
            "default": false,
            "title": "Search Index",
            "type": "boolean"
          }
        },
        "title": "RepresentationState",
        "type": "object"
      },
      "ResultState": {
        "description": "Why ``Job.result`` is null.\n\n``available`` with a null result means the job has not succeeded yet;\n``expired`` means its content was removed; ``not_retained`` means the client is\nprovisioned ``zero_retention`` and already had its one chance to read it;\n``cancelled`` means the job, or the root job it ran for, was cancelled. A\ncancelled job serves no results (it is not charged, including delivered parts) — not its\nown progressive values, and not a delegated child's result. It is a read\nstate only, derived on the wire; no row stores it.\n``storage_unavailable`` withholds a retained result while its workspace binding\nrefuses access; ``Job.result_error`` explains the current refusal.\nA late poll returns the job with a state, never a 404 — \"this expired\" and\n\"this never existed\" are a scheduling problem and a bug respectively, and a\n404 makes them identical.",
        "enum": [
          "available",
          "expired",
          "not_retained",
          "cancelled",
          "storage_unavailable"
        ],
        "title": "ResultState",
        "type": "string"
      },
      "RoleSourceWire": {
        "additionalProperties": false,
        "description": "Physical ownership, independent of the line/header grain convention.",
        "properties": {
          "column": {
            "description": "Column on the owning table.",
            "title": "Column",
            "type": "string"
          },
          "evidence": {
            "description": "Binding slot, source profile, exact alias, or sole typed date.",
            "title": "Evidence",
            "type": "string"
          },
          "table": {
            "description": "Physical table owning the role.",
            "title": "Table",
            "type": "string"
          }
        },
        "required": [
          "table",
          "column",
          "evidence"
        ],
        "title": "RoleSourceWire",
        "type": "object"
      },
      "RowRange": {
        "additionalProperties": false,
        "description": "A 0-based inclusive row run on a parquet table.",
        "properties": {
          "column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Column"
          },
          "end_row": {
            "minimum": 0.0,
            "title": "End Row",
            "type": "integer"
          },
          "kind": {
            "const": "row_range",
            "default": "row_range",
            "title": "Kind",
            "type": "string"
          },
          "start_row": {
            "minimum": 0.0,
            "title": "Start Row",
            "type": "integer"
          }
        },
        "required": [
          "start_row",
          "end_row"
        ],
        "title": "RowRange",
        "type": "object"
      },
      "RowRangeQueryRegion": {
        "additionalProperties": false,
        "description": "A verified region on a pageable tabular artifact, addressed by row number.\n\nA parquet upload stored as-is uses its own row order. A jsonl or parquet\nderivative uses the queried artifact's row order; ``derivative_path`` names\nthat artifact when it differs from the caller-facing ``source_path``.",
        "properties": {
          "basis": {
            "default": "verified",
            "description": "How this region was established. 'verified': a claim whose cited value was mechanically re-computed from exactly these rows. 'inputs': one table's contribution to a derived (multi-table) figure — the rows were verified to match the claim's filters, but the figure itself is not re-computable from this table alone. 'provenance': no claim covered this query, so the region records what the query's captured provenance proved it read — never a whole-table guess. Absent on legacy payloads, which are all 'verified'.",
            "enum": [
              "verified",
              "inputs",
              "provenance"
            ],
            "title": "Basis",
            "type": "string"
          },
          "bounding": {
            "default": false,
            "description": "True when this is a bounding range over a large match set rather than exact runs.",
            "title": "Bounding",
            "type": "boolean"
          },
          "columns": {
            "description": "Cited column names, in table order.",
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "derivative_path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pageable derivative (parquet or jsonl) when it is not the uploaded source itself.",
            "title": "Derivative Path"
          },
          "end_row": {
            "description": "Last row of the run, 0-based and inclusive.",
            "title": "End Row",
            "type": "integer"
          },
          "filter_columns": {
            "description": "Columns the verified claim filtered on to select these rows, minus any already in columns. Empty on legacy payloads.",
            "items": {
              "type": "string"
            },
            "title": "Filter Columns",
            "type": "array"
          },
          "kind": {
            "const": "row_range",
            "default": "row_range",
            "title": "Kind",
            "type": "string"
          },
          "matched_rows": {
            "default": 0,
            "description": "How many source rows the region covers.",
            "title": "Matched Rows",
            "type": "integer"
          },
          "read_columns": {
            "description": "Columns the query read from this table (output lineage), minus any already in columns or filter_columns. Populated on a 'provenance'-basis region only; empty otherwise and on legacy payloads.",
            "items": {
              "type": "string"
            },
            "title": "Read Columns",
            "type": "array"
          },
          "region_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Opaque identity for paging this exact region when a receipt has several regions on one file.",
            "title": "Region Id"
          },
          "runs": {
            "description": "Exact matched-row runs inside the span, so a bounding range stays pageable as matches only. May cover fewer than matched_rows when the verifier truncated its run list; empty on legacy payloads.",
            "items": {
              "$ref": "#/components/schemas/ArtifactRowRun"
            },
            "title": "Runs",
            "type": "array"
          },
          "runs_replayable": {
            "default": false,
            "description": "True only when grounding-rows can reconstruct this exact region predicate for pages beyond runs. Regions without a safe replay fail closed instead of returning broader rows.",
            "title": "Runs Replayable",
            "type": "boolean"
          },
          "runs_truncated": {
            "default": false,
            "description": "True when runs is an exact ordered prefix of matched islands and more matched rows exist. Later pages require guarded replay; false when the runs are complete or on legacy payloads.",
            "title": "Runs Truncated",
            "type": "boolean"
          },
          "scan_index": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which scan of the query read these rows, when the region records one scan rather than the whole table. A query can read one file more than once — a narrow CTE and a broad one, say — and each such scan grounds separately, so this identifies the scan to replay for further row pages. Absent on a whole-table span, on verified regions, and on legacy payloads.",
            "title": "Scan Index"
          },
          "scan_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The scan named the way the query spells it: 'main query', 'CTE <name>', or 'subquery <n>'. Present exactly when scan_index is.",
            "title": "Scan Label"
          },
          "source_path": {
            "description": "Uploaded file path this region belongs to.",
            "title": "Source Path",
            "type": "string"
          },
          "start_row": {
            "description": "First row of the run, 0-based and inclusive.",
            "title": "Start Row",
            "type": "integer"
          }
        },
        "required": [
          "source_path",
          "start_row",
          "end_row"
        ],
        "title": "RowRangeQueryRegion",
        "type": "object"
      },
      "RunSqlRequest": {
        "additionalProperties": false,
        "description": "One read-only SELECT over the workspace's queryable tables.\n\nTable names come from metadata — ``file-metadata`` publishes each\nqueryable tab's ``table_name`` and ``folder-metadata``'s table census\nlists them all — and from earlier run-sql results (every response's\n``res_…`` handle is a registered table on the next call, so results can\nbe joined, aggregated, or paged with LIMIT/OFFSET). Joins across files\nare ordinary SQL joins. A statement that is not a read, or that reads an\nunregistered table, is refused with ``invalid_request`` naming the rule\nand the registered tables.",
        "properties": {
          "sql": {
            "description": "One read-only SELECT (DuckDB dialect) over the registered tables and earlier `res_…` handles.",
            "maxLength": 4096,
            "minLength": 1,
            "title": "Sql",
            "type": "string"
          }
        },
        "required": [
          "sql"
        ],
        "title": "RunSqlRequest",
        "type": "object"
      },
      "RunSqlResponse": {
        "additionalProperties": false,
        "description": "One executed statement: shape, bounded preview, and the retained result.\n\nThe stored result is complete whatever the preview shows;\n``result_citation.result_file.download_url`` fetches the whole parquet.\n``duplicate`` marks a statement answered from an earlier identical run's\nstored result — safe to build on, and free once an earlier run of it has been billed.",
        "properties": {
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "duplicate": {
            "default": false,
            "title": "Duplicate",
            "type": "boolean"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The external operation job; absent for commands inside a search job.",
            "title": "Job Id"
          },
          "result": {
            "$ref": "#/components/schemas/QueryTablePreview"
          },
          "result_citation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QueryTableCitation"
              },
              {
                "type": "null"
              }
            ]
          },
          "result_materialization_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Result Materialization Error"
          },
          "source_paths": {
            "description": "The uploaded files the statement read — carried on the response itself so source attribution survives when no result file is materialized (job-attributed agent statements).",
            "items": {
              "type": "string"
            },
            "title": "Source Paths",
            "type": "array"
          },
          "sql": {
            "description": "The normalized statement that ran — the result's provenance.",
            "title": "Sql",
            "type": "string"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "sql",
          "result"
        ],
        "title": "RunSqlResponse",
        "type": "object"
      },
      "RunSqlResult": {
        "additionalProperties": false,
        "properties": {
          "output": {
            "$ref": "#/components/schemas/RunSqlResponse",
            "description": "The operation response returned to the caller, retained with its job."
          },
          "result_type": {
            "const": "run_sql",
            "default": "run_sql",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "output"
        ],
        "title": "RunSqlResult",
        "type": "object"
      },
      "SchemaError": {
        "additionalProperties": false,
        "description": "One violation from ``POST /v1/extract/schema-validation``.",
        "properties": {
          "message": {
            "description": "Why this node is not accepted as an extract schema.",
            "title": "Message",
            "type": "string"
          },
          "path": {
            "description": "JSON Pointer of the schema node that failed validation.",
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path",
          "message"
        ],
        "title": "SchemaError",
        "type": "object"
      },
      "ScoreAnswer": {
        "additionalProperties": false,
        "properties": {
          "confidence": {
            "description": "The decision model's average confidence in this answer, from 0 to 1. Lower means it was less sure; it is not the probability of any one level.",
            "title": "Confidence",
            "type": "number"
          },
          "legend": {
            "description": "The scale's levels in order, lowest first, as the question named them.",
            "items": {
              "type": "string"
            },
            "title": "Legend",
            "type": "array"
          },
          "probabilities": {
            "additionalProperties": {
              "type": "number"
            },
            "description": "Each level's probability, keyed by its index in the legend.",
            "title": "Probabilities",
            "type": "object"
          },
          "score": {
            "description": "Expected position on the scale, from 0 (the first level) to the last level's index.",
            "title": "Score",
            "type": "number"
          },
          "type": {
            "const": "score",
            "default": "score",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "score",
          "legend",
          "probabilities",
          "confidence"
        ],
        "title": "ScoreAnswer",
        "type": "object"
      },
      "ScoreQuestion": {
        "additionalProperties": false,
        "description": "Place the state on an ordered scale. Its answer is a score along the levels.",
        "properties": {
          "criteria": {
            "description": "The ordered levels of the scale, lowest first.",
            "items": {
              "type": "string"
            },
            "maxItems": 255,
            "minItems": 1,
            "title": "Criteria",
            "type": "array"
          },
          "instructions": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question that the scale answers.",
            "title": "Instructions"
          },
          "type": {
            "const": "score",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "type",
          "criteria"
        ],
        "title": "ScoreQuestion",
        "type": "object"
      },
      "ScoredCategory": {
        "additionalProperties": false,
        "properties": {
          "category": {
            "title": "Category",
            "type": "string"
          },
          "confidence": {
            "title": "Confidence",
            "type": "number"
          }
        },
        "required": [
          "category",
          "confidence"
        ],
        "title": "ScoredCategory",
        "type": "object"
      },
      "SearchEvidence": {
        "additionalProperties": false,
        "description": "One piece of evidence the search agent cited, named as the caller's own file.\n\nThe agent retrieves from workspace-internal ingestion derivatives, but those\nare an implementation detail the caller never addresses: every citation is\nresolved server-side, through the caller's access gate, to the uploaded file\nit belongs to (``source_path`` + ``source_file_id``). A citation that cannot be\nresolved to a visible file — hallucinated, deleted mid-run, or access-refused —\nis dropped rather than published under a path the caller cannot use.\n\nNo locator: pinning a quote to a region of the original document is a\nseparate ``ground`` call the caller makes on the file at ``source_path``\n(``source_file_id``). Ground ``quote`` as the target text, or each entry of\n``passages`` as its own target when that list is present. For a quote taken\nfrom a spreadsheet, pass ``component`` as the target's ``sheet``.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Public component of the file the quote came from — the tab name for a spreadsheet, the section for a split document; the same vocabulary file-metadata lists. Pass it as the ground target's sheet when grounding a spreadsheet quote. None for a single-component file or when attribution was unavailable.",
            "title": "Component"
          },
          "derivation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DerivationTrace"
              },
              {
                "type": "null"
              }
            ],
            "description": "Computation DAG for derived answers; None when the evidence is a direct extraction or the run recorded no dependency edges."
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "1-based page number, when the agent saw one.",
            "title": "Page"
          },
          "passages": {
            "description": "Contiguous pieces of the source file that quote was stitched from, in the file's own text. Ground each piece as its own target when this list is present, with max_matches 2. A piece that returns two matches repeats in the file, so which copy the quote used is unknown. A ' | ' marks a table cell boundary added by the check. Replace it with a space before grounding. Filled only for PDF, Word and PowerPoint sources that Ground reads from the PDF text layer. Absent when quote is already one contiguous passage, could not be checked, or could not be verified.",
            "items": {
              "type": "string"
            },
            "title": "Passages",
            "type": "array"
          },
          "queries": {
            "description": "The SQL the run executed over this evidence's table, with a bounded preview of each result — server-recorded from the run's tables engine, never model-authored. Attached whenever the run queried the cited table (or the row extraction of the same spreadsheet tab), so a verbatim quote from a queried sheet carries the computation trail alongside it; empty when the run never queried the cited file's tables.",
            "items": {
              "$ref": "#/components/schemas/TableQueryGrounding"
            },
            "title": "Queries",
            "type": "array"
          },
          "quote": {
            "description": "The key passage, as retrieved from the file.",
            "title": "Quote",
            "type": "string"
          },
          "relevance": {
            "default": "",
            "description": "Deprecated: empty on new results, where `reasoning` says how the evidences support the answer.",
            "title": "Relevance",
            "type": "string"
          },
          "source_file_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The id of the file at source_path, resolved server-side. Always set on newly finalized results; null only on results stored before unresolvable citations were dropped.",
            "title": "Source File Id"
          },
          "source_path": {
            "description": "The uploaded file the quote belongs to, e.g. 'reports/policy.pdf'. This is the file to ground the quote against.",
            "title": "Source Path",
            "type": "string"
          }
        },
        "required": [
          "source_path",
          "quote"
        ],
        "title": "SearchEvidence",
        "type": "object"
      },
      "SearchLlmUsage": {
        "additionalProperties": false,
        "description": "What answering one search query cost in LLM work.\n\nPresent only when the run was asked to account for itself *and* spend reached its\nledger; ``null`` otherwise, so a caller can tell \"nothing was measured\" from\n\"nothing was spent\". An empty ledger publishes ``null`` rather than a zeroed\nobject for that reason: zeros would claim a measured run cost nothing, when what\nan empty ledger most likely records is accounting that never landed.\n\nThe totals cover recorded model calls at any depth: the agent's own\nturns, and the calls the retrieval tools made on its behalf — a document read by\nthe recursive-LLM engine, a scan cracked by the vision engine, a tables question\nanswered by the SQL agent. That is the number a per-query cost figure needs, and it\nis invariably several times the agent's own turn count.\n\n``by_model`` is the same spend split by the model that served it, because a run\nlegitimately spends on several at different prices — a total alone cannot be turned\ninto money. The totals are the sum of ``by_model`` and are published anyway so the\ncommon case needs no arithmetic.\n\nObserved retries are included. These public token totals are not a complete cost\ncertificate: provider omissions and failed persistence can leave gaps. Internal\ncoverage and non-token counters stay in the ledger and are not added to this wire\nshape without a separate SDK contract update.",
        "properties": {
          "by_model": {
            "description": "The same spend per model that served it, highest first.",
            "items": {
              "$ref": "#/components/schemas/ModelTokenUsage"
            },
            "title": "By Model",
            "type": "array"
          },
          "cached_input_tokens": {
            "default": 0,
            "description": "The share of input_tokens served from a provider prompt cache — billed at a reduced rate, so it is reported separately rather than subtracted.",
            "title": "Cached Input Tokens",
            "type": "integer"
          },
          "input_tokens": {
            "default": 0,
            "description": "Prompt tokens across every request, cached ones included.",
            "title": "Input Tokens",
            "type": "integer"
          },
          "output_tokens": {
            "default": 0,
            "description": "Completion tokens across every request.",
            "title": "Output Tokens",
            "type": "integer"
          },
          "requests": {
            "default": 0,
            "description": "Completed LLM requests, tool-internal ones included.",
            "title": "Requests",
            "type": "integer"
          }
        },
        "title": "SearchLlmUsage",
        "type": "object"
      },
      "SearchResponse": {
        "additionalProperties": false,
        "description": "Response of ``hybrid-search``.\n\n``candidates_seen`` is the pre-access-filter count so the caller can tell\nwhen truncation happened upstream of the access gate.\n\nEvery ``hits[].path`` is an uploaded **source** path. Each hit also carries the\ningestion derivative it was actually read from, but those fields are internal\nto the host (the agent tools address files that way) and are excluded from this\nbody — a ``/v1`` caller only ever sees the files it uploaded.",
        "properties": {
          "candidates_seen": {
            "title": "Candidates Seen",
            "type": "integer"
          },
          "coverage": {
            "$ref": "#/components/schemas/Coverage"
          },
          "credits": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Credits billed for this call; zero for a free answer or replay, null when a billing receipt is unavailable.",
            "title": "Credits"
          },
          "hits": {
            "items": {
              "$ref": "#/components/schemas/Evidence"
            },
            "title": "Hits",
            "type": "array"
          },
          "job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The external operation job; absent for commands inside a search job.",
            "title": "Job Id"
          },
          "truncated": {
            "title": "Truncated",
            "type": "boolean"
          },
          "waiver": {
            "anyOf": [
              {
                "enum": [
                  "repeat_of_job",
                  "no_job"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why this call is free: repeat_of_job reuses an earlier answer; no_job answers without creating a job.",
            "title": "Waiver"
          }
        },
        "required": [
          "hits",
          "candidates_seen",
          "truncated",
          "coverage"
        ],
        "title": "SearchResponse",
        "type": "object"
      },
      "SheetQueryRegion": {
        "additionalProperties": false,
        "description": "A verified region on a source file with an addressable grid.\n\nCoordinates are expressed in the caller's uploaded workbook or CSV, never\nin the internal parquet derivative.",
        "properties": {
          "a1_range": {
            "description": "A1 range on the original sheet, e.g. 'B12:D15'.",
            "title": "A1 Range",
            "type": "string"
          },
          "basis": {
            "default": "verified",
            "description": "How this region was established. 'verified': a claim whose cited value was mechanically re-computed from exactly these rows. 'inputs': one table's contribution to a derived (multi-table) figure — the rows were verified to match the claim's filters, but the figure itself is not re-computable from this table alone. 'provenance': no claim covered this query, so the region records what the query's captured provenance proved it read — never a whole-table guess. Absent on legacy payloads, which are all 'verified'.",
            "enum": [
              "verified",
              "inputs",
              "provenance"
            ],
            "title": "Basis",
            "type": "string"
          },
          "bounding": {
            "default": false,
            "description": "True when this is a bounding box over a large match set rather than exact runs.",
            "title": "Bounding",
            "type": "boolean"
          },
          "kind": {
            "const": "sheet",
            "default": "sheet",
            "title": "Kind",
            "type": "string"
          },
          "matched_rows": {
            "default": 0,
            "description": "How many source rows the region covers.",
            "title": "Matched Rows",
            "type": "integer"
          },
          "scan_index": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which scan of the query read these rows, when the region records one scan rather than the whole table. A query can read one file more than once — a narrow CTE and a broad one, say — and each such scan grounds separately, so this identifies the scan to replay for further row pages. Absent on a whole-table span, on verified regions, and on legacy payloads.",
            "title": "Scan Index"
          },
          "scan_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The scan named the way the query spells it: 'main query', 'CTE <name>', or 'subquery <n>'. Present exactly when scan_index is.",
            "title": "Scan Label"
          },
          "sheet_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workbook tab, when applicable.",
            "title": "Sheet Name"
          },
          "source_path": {
            "description": "Uploaded file path this region points at.",
            "title": "Source Path",
            "type": "string"
          }
        },
        "required": [
          "source_path",
          "a1_range"
        ],
        "title": "SheetQueryRegion",
        "type": "object"
      },
      "SheetRange": {
        "additionalProperties": false,
        "description": "A cell range on a spreadsheet sheet.",
        "properties": {
          "a1_range": {
            "description": "A1 cell range on that sheet, for example B12:D15.",
            "title": "A1 Range",
            "type": "string"
          },
          "kind": {
            "const": "sheet_range",
            "default": "sheet_range",
            "title": "Kind",
            "type": "string"
          },
          "sheet": {
            "description": "Workbook tab name this range belongs to.",
            "title": "Sheet",
            "type": "string"
          }
        },
        "required": [
          "sheet",
          "a1_range"
        ],
        "title": "SheetRange",
        "type": "object"
      },
      "SignedAmount": {
        "additionalProperties": false,
        "properties": {
          "column": {
            "description": "Signed amount column on every primary member.",
            "minLength": 1,
            "title": "Column",
            "type": "string"
          },
          "kind": {
            "const": "signed",
            "description": "One signed amount column.",
            "title": "Kind",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "column"
        ],
        "title": "SignedAmount",
        "type": "object"
      },
      "SkippedCheckWire": {
        "additionalProperties": false,
        "description": "One check the battery could not run, and why.",
        "properties": {
          "check": {
            "description": "Which question of the integrity battery went unanswered, by its check id.",
            "title": "Check",
            "type": "string"
          },
          "reason": {
            "description": "Which role was missing, or the error the statement returned.",
            "title": "Reason",
            "type": "string"
          }
        },
        "required": [
          "check",
          "reason"
        ],
        "title": "SkippedCheckWire",
        "type": "object"
      },
      "SourceIncompleteDisclosure": {
        "additionalProperties": false,
        "description": "The source file ended mid-document, so the result covers only the part that arrived.\n\nThe job succeeded on the bytes that were present, and a lane that can read a\npartial file still returns everything it could read. Without this disclosure\nthat output is indistinguishable from a complete document, which is the\ndangerous reading: a short result looks like a short source.\n\nNo original size is published because an incomplete file carries no record of\nhow long it should have been. ``received_bytes`` is what a caller can compare\nagainst the size it believes it sent.",
        "properties": {
          "code": {
            "const": "source_incomplete",
            "title": "Code",
            "type": "string"
          },
          "received_bytes": {
            "description": "Size of the file as received, whose final record ended before the record did.",
            "minimum": 1.0,
            "title": "Received Bytes",
            "type": "integer"
          }
        },
        "required": [
          "code",
          "received_bytes"
        ],
        "title": "SourceIncompleteDisclosure",
        "type": "object"
      },
      "SplitArtifact": {
        "additionalProperties": false,
        "properties": {
          "url": {
            "description": "Authenticated URL of a materialized file for this segment.",
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url"
        ],
        "title": "SplitArtifact",
        "type": "object"
      },
      "SplitCategory": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "instance_key": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SplitInstanceKey"
              },
              {
                "type": "null"
              }
            ]
          },
          "label": {
            "title": "Label",
            "type": "string"
          },
          "subclasses": {
            "items": {
              "$ref": "#/components/schemas/SplitSubclass"
            },
            "title": "Subclasses",
            "type": "array"
          }
        },
        "required": [
          "id",
          "label"
        ],
        "title": "SplitCategory",
        "type": "object"
      },
      "SplitConfidence": {
        "additionalProperties": false,
        "properties": {
          "band": {
            "default": "unavailable",
            "description": "Coarse confidence band for this split decision.",
            "enum": [
              "unavailable",
              "low",
              "medium",
              "high"
            ],
            "title": "Band",
            "type": "string"
          },
          "score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Numeric score when the runtime produced one. Null otherwise.",
            "title": "Score"
          }
        },
        "title": "SplitConfidence",
        "type": "object"
      },
      "SplitInstance": {
        "additionalProperties": false,
        "properties": {
          "key": {
            "description": "Instance-key name from the request class, when instance splitting ran.",
            "title": "Key",
            "type": "string"
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Extracted instance-key value for this segment.",
            "title": "Value"
          }
        },
        "required": [
          "key"
        ],
        "title": "SplitInstance",
        "type": "object"
      },
      "SplitInstanceKey": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "title": "Description",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "required": {
            "default": false,
            "title": "Required",
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "description"
        ],
        "title": "SplitInstanceKey",
        "type": "object"
      },
      "SplitJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "split",
            "default": "split",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SplitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "SplitJob",
        "type": "object"
      },
      "SplitOutputOptions": {
        "additionalProperties": false,
        "properties": {
          "include_content": {
            "default": false,
            "description": "When true, each segment includes its extracted markdown in content.",
            "title": "Include Content",
            "type": "boolean"
          },
          "materialize_files": {
            "default": false,
            "description": "When true, each document segment includes a downloadable artifact URL. Spreadsheet segments always include a single-sheet XLSX URL, even when this is false.",
            "title": "Materialize Files",
            "type": "boolean"
          }
        },
        "title": "SplitOutputOptions",
        "type": "object"
      },
      "SplitRequest": {
        "additionalProperties": false,
        "description": "Canonical schema for packet splitting.\n\nDocuments split into logical page-range segments. Spreadsheets split\ndeterministically into one materialized XLSX artifact per worksheet and\nclassify each worksheet against ``classes``.",
        "properties": {
          "classes": {
            "description": "Document classes to split the packet into; spreadsheets classify worksheets against these classes.",
            "items": {
              "$ref": "#/components/schemas/SplitCategory"
            },
            "minItems": 1,
            "title": "Classes",
            "type": "array"
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "output": {
            "$ref": "#/components/schemas/SplitOutputOptions",
            "description": "Whether segments include markdown content and/or materialized file URLs."
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "overlap_policy": {
            "default": "exclusive",
            "description": "Whether a boundary page may belong to two adjacent segments or only one.",
            "enum": [
              "exclusive",
              "shared_boundary_page"
            ],
            "title": "Overlap Policy",
            "type": "string"
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive page ranges to consider. Omit to use the whole document.",
            "title": "Page Ranges"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the Parse that runs before this operation, using the same fields as Parse. Omit to use the default Parse. parse.parse_mode and the top-level parse_mode must agree when both are set, and so must parse.page_ranges and page_ranges. A setting that does not apply is reported in warnings."
          },
          "parse_mode": {
            "default": "low",
            "description": "How much parsing effort to use: Low uses native OCR, Medium routes to the best parser, and High adds page verification and correction.",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Parse Mode",
            "type": "string"
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "quality": {
            "default": "auto",
            "description": "Latency versus accuracy preference for this run. Only auto is accepted today.",
            "enum": [
              "auto",
              "fast",
              "accurate"
            ],
            "title": "Quality",
            "type": "string"
          },
          "source": {
            "description": "The packet to split: a fresh upload, an HTTPS URL, a workspace file, or a prior parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          },
          "split_rules": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional free-text guidance for how to cut the packet (for example, split on cover sheets).",
            "title": "Split Rules"
          },
          "unknown_policy": {
            "default": "include",
            "description": "What to do with pages that match no class. include keeps them as unclassified; force assigns the best class; error fails the job.",
            "enum": [
              "include",
              "force",
              "error"
            ],
            "title": "Unknown Policy",
            "type": "string"
          }
        },
        "required": [
          "source",
          "classes"
        ],
        "title": "SplitRequest",
        "type": "object"
      },
      "SplitRequestEcho": {
        "additionalProperties": false,
        "description": "A stored ``split`` request, read back.",
        "properties": {
          "classes": {
            "description": "Document classes to split the packet into; spreadsheets classify worksheets against these classes.",
            "items": {
              "$ref": "#/components/schemas/SplitCategory"
            },
            "minItems": 1,
            "title": "Classes",
            "type": "array"
          },
          "corpus_sources": {
            "description": "Workspace files visible in the run tray, including files not submitted by this request.",
            "items": {
              "$ref": "#/components/schemas/WorkspaceFileSource"
            },
            "maxItems": 50,
            "title": "Corpus Sources",
            "type": "array"
          },
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional display name. Public Parse, Split, Classify, Extract, and Ground runs use a stable server default when blank. The console calls a named run a 'project'.",
            "title": "Name"
          },
          "output": {
            "$ref": "#/components/schemas/SplitOutputOptions",
            "description": "Whether segments include markdown content and/or materialized file URLs."
          },
          "output_workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workspace for retained result artifacts. Defaults to the unique source workspace, or a reused Parse's output workspace. Required for ambiguous destinations involving customer storage. Does not change source access.",
            "title": "Output Workspace Id"
          },
          "overlap_policy": {
            "default": "exclusive",
            "description": "Whether a boundary page may belong to two adjacent segments or only one.",
            "enum": [
              "exclusive",
              "shared_boundary_page"
            ],
            "title": "Overlap Policy",
            "type": "string"
          },
          "page_ranges": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PageRange"
                },
                "maxItems": 200,
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "One-based inclusive page ranges to consider. Omit to use the whole document.",
            "title": "Page Ranges"
          },
          "parse": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ParseSettings"
              },
              {
                "type": "null"
              }
            ],
            "description": "Settings for the Parse that runs before this operation, using the same fields as Parse. Omit to use the default Parse. parse.parse_mode and the top-level parse_mode must agree when both are set, and so must parse.page_ranges and page_ranges. A setting that does not apply is reported in warnings."
          },
          "parse_mode": {
            "default": "low",
            "description": "How much parsing effort to use: Low uses native OCR, Medium routes to the best parser, and High adds page verification and correction.",
            "enum": [
              "low",
              "medium",
              "high"
            ],
            "title": "Parse Mode",
            "type": "string"
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id; jobs submitted together share it. Not a server-side resource.",
            "title": "Project Id"
          },
          "quality": {
            "default": "auto",
            "description": "Latency versus accuracy preference for this run. Only auto is accepted today.",
            "enum": [
              "auto",
              "fast",
              "accurate"
            ],
            "title": "Quality",
            "type": "string"
          },
          "request_type": {
            "const": "split",
            "default": "split",
            "title": "Request Type",
            "type": "string"
          },
          "source": {
            "description": "The packet to split: a fresh upload, an HTTPS URL, a workspace file, or a prior parse job.",
            "discriminator": {
              "mapping": {
                "parse_result": "#/components/schemas/ParseResultSource",
                "upload": "#/components/schemas/UploadSource",
                "url": "#/components/schemas/UrlSource",
                "workspace_file": "#/components/schemas/WorkspaceFileSource"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/UploadSource"
              },
              {
                "$ref": "#/components/schemas/UrlSource"
              },
              {
                "$ref": "#/components/schemas/WorkspaceFileSource"
              },
              {
                "$ref": "#/components/schemas/ParseResultSource"
              }
            ],
            "title": "Source"
          },
          "split_rules": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional free-text guidance for how to cut the packet (for example, split on cover sheets).",
            "title": "Split Rules"
          },
          "unknown_policy": {
            "default": "include",
            "description": "What to do with pages that match no class. include keeps them as unclassified; force assigns the best class; error fails the job.",
            "enum": [
              "include",
              "force",
              "error"
            ],
            "title": "Unknown Policy",
            "type": "string"
          }
        },
        "required": [
          "source",
          "classes"
        ],
        "title": "SplitRequestEcho",
        "type": "object"
      },
      "SplitResult": {
        "additionalProperties": false,
        "properties": {
          "file_name": {
            "description": "Source filename recorded for this run.",
            "title": "File Name",
            "type": "string"
          },
          "lane": {
            "description": "Which parser lane produced this payload, for example document or spreadsheet.",
            "title": "Lane",
            "type": "string"
          },
          "page_count": {
            "description": "Pages considered while splitting.",
            "title": "Page Count",
            "type": "integer"
          },
          "result_type": {
            "const": "split",
            "default": "split",
            "title": "Result Type",
            "type": "string"
          },
          "segments": {
            "description": "Ordered packet segments, including unclassified ones when allowed.",
            "items": {
              "$ref": "#/components/schemas/SplitSegment"
            },
            "title": "Segments",
            "type": "array"
          },
          "units": {
            "description": "Measured work units for this split. The job's `credits` is the final billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "warnings": {
            "description": "Parse settings this run accepted but did not apply, each naming the setting and why, for example a page selection on a file with no pages. Left out when empty.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "file_name",
          "lane",
          "page_count",
          "segments",
          "units"
        ],
        "title": "SplitResult",
        "type": "object"
      },
      "SplitSegment": {
        "additionalProperties": false,
        "properties": {
          "artifacts": {
            "description": "Downloadable files when output.materialize_files is true. Spreadsheet segments always include a single-sheet XLSX URL even when that flag is false.",
            "items": {
              "$ref": "#/components/schemas/SplitArtifact"
            },
            "title": "Artifacts",
            "type": "array"
          },
          "boundary_confidence": {
            "$ref": "#/components/schemas/SplitConfidence",
            "description": "How confident the start and end page cut is."
          },
          "class": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SplitSegmentCategory"
              },
              {
                "type": "null"
              }
            ],
            "description": "The winning request class for a matched segment. Null when unclassified. JSON name is class; the Python SDK attribute is split_class."
          },
          "classes": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/SplitSegmentCategory"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Alternate class assignments when more than one class applied.",
            "title": "Classes"
          },
          "classification_confidence": {
            "$ref": "#/components/schemas/SplitConfidence",
            "description": "How confident the assigned class is for this segment."
          },
          "content": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Segment markdown when output.include_content is true. Null otherwise.",
            "title": "Content"
          },
          "end_page": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Inclusive last page of this cut. For workbooks, equals start_page.",
            "title": "End Page"
          },
          "id": {
            "description": "Stable id of this cut within the split result.",
            "title": "Id",
            "type": "string"
          },
          "instance": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SplitInstance"
              },
              {
                "type": "null"
              }
            ],
            "description": "Instance-key value when the request class asked for instance splitting."
          },
          "json_pointer": {
            "anyOf": [
              {
                "pattern": "^(?:$|/)",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "JSON Pointer into a structured source when the cut is not a page range.",
            "title": "Json Pointer"
          },
          "sequence": {
            "description": "0-based order of this segment in the packet.",
            "minimum": 0.0,
            "title": "Sequence",
            "type": "integer"
          },
          "sheet_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Workbook tab for a spreadsheet segment. Null for PDFs.",
            "title": "Sheet Name"
          },
          "start_page": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Inclusive first page of this cut. For workbooks, equals sheet_index + 1.",
            "title": "Start Page"
          },
          "status": {
            "description": "Whether this cut was assigned a class. matched has class (Python SDK: split_class); unclassified was kept because unknown_policy is include.",
            "enum": [
              "matched",
              "unclassified"
            ],
            "title": "Status",
            "type": "string"
          },
          "warnings": {
            "description": "Non-fatal notes about this segment, such as a forced class assignment.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "id",
          "sequence",
          "status"
        ],
        "title": "SplitSegment",
        "type": "object"
      },
      "SplitSegmentCategory": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "default": "",
            "description": "Caller-supplied description of what belongs in this class.",
            "title": "Description",
            "type": "string"
          },
          "id": {
            "description": "Stable id of the class this segment was assigned.",
            "title": "Id",
            "type": "string"
          },
          "label": {
            "description": "Display name of the assigned class.",
            "title": "Label",
            "type": "string"
          },
          "parent_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Parent class id when this assignment is a subclass.",
            "title": "Parent Id"
          },
          "subcategory_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Subclass id when the segment matched a nested class.",
            "title": "Subcategory Id"
          }
        },
        "required": [
          "id",
          "label"
        ],
        "title": "SplitSegmentCategory",
        "type": "object"
      },
      "SplitSubclass": {
        "additionalProperties": false,
        "properties": {
          "description": {
            "default": "",
            "title": "Description",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "label": {
            "title": "Label",
            "type": "string"
          }
        },
        "required": [
          "id",
          "label"
        ],
        "title": "SplitSubclass",
        "type": "object"
      },
      "SpreadsheetRange": {
        "additionalProperties": false,
        "properties": {
          "a1_range": {
            "title": "A1 Range",
            "type": "string"
          },
          "kind": {
            "const": "spreadsheet_range",
            "default": "spreadsheet_range",
            "title": "Kind",
            "type": "string"
          },
          "sheet": {
            "title": "Sheet",
            "type": "string"
          }
        },
        "required": [
          "sheet",
          "a1_range"
        ],
        "title": "SpreadsheetRange",
        "type": "object"
      },
      "SqlReceipt": {
        "additionalProperties": false,
        "description": "One SQL statement a journal-entry-testing run executed, with its result.\n\nThe audit trail of a JET answer: every headline figure is meant to be\nreadable out of one of these. Unlike\n:class:`TableQueryGrounding` — whose SQL is written by a sub-agent and\npublished as supporting detail — the statement here is the deliverable's\nown working, so it is published whole rather than digested.\n\n``rows`` is bounded (``JET_RECEIPT_MAX_ROWS``) and ``truncated`` says\nwhether the bound cut anything, so an \"every exception is listed\" reading\nis never made from a silently capped table. ``result_row_count`` is the\nfigure that reading actually needs: the statement's whole result is stored,\nand this is its size, whatever the bound carried below.",
        "properties": {
          "columns": {
            "description": "Result column names, in result order.",
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "executor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The named executor that generated this statement (`reconcile_movement`, `test_timing`, `find_duplicates`, `field_completeness`, `journal_balance`), when one did, `custom_sql` for a statement the fixed-pipeline engine authored under its escape, or `ledger_understanding` for the ledger-understanding census's own statement, which ran before this run and is cited rather than re-run. Null when no named generator produced it — a population count, an absence probe, or SQL the agent wrote itself. Both engines use the same words here.",
            "title": "Executor"
          },
          "grounding_status": {
            "anyOf": [
              {
                "enum": [
                  "exact",
                  "unavailable",
                  "zero_result"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Whether this statement's stored result already carried proof of which source rows it read when the receipt was recorded. 'exact' means it did; 'unavailable' means the proof could not be read; 'zero_result' means there were no rows to ground. Null when nothing had been captured yet — the ordinary case for a lane that captures at publication time, so this is a record of what execution happened to know and NOT a prediction of whether the receipt can be grounded. What was actually proven is published as `grounding_status` on the matching evidence query, beside the `regions` it earned.",
            "title": "Grounding Status"
          },
          "handle": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Content-addressed key of this statement's stored result, derived from the statement text. Server-side identity: it is what lets the run's own publication find the stored result and its capture-time provenance, and it is NOT an address an agent may query or chain from — `result_id` is the identity the caller and the row pager use. Null on a run that stored no result for the statement. A `cat_` handle names an exploratory document-catalog query: it stores no result beyond the rows carried here.",
            "title": "Handle"
          },
          "parameters": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "The executor's resolved call, flattened to text — the clock and its true grain, the window's day offsets, the signature, the tolerance, the population. Empty on a statement no executor generated. This is what makes a figure trace to a named, parameterized computation rather than to SQL alone.",
            "title": "Parameters",
            "type": "object"
          },
          "replay": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SqlReplayReceipt"
              },
              {
                "type": "null"
              }
            ],
            "description": "Independent recomputation metadata for this statement; null on legacy results."
          },
          "result_id": {
            "description": "Stable per-run identity of this statement, in execution order (e.g. 'sql_3').",
            "title": "Result Id",
            "type": "string"
          },
          "result_row_count": {
            "default": 0,
            "description": "Rows in the statement's complete stored result. Equal to `row_count` when nothing was cut; the number a total or an exception count must be read from when `truncated` is set.",
            "title": "Result Row Count",
            "type": "integer"
          },
          "row_count": {
            "default": 0,
            "description": "Rows carried below — not the statement's unbounded result size.",
            "title": "Row Count",
            "type": "integer"
          },
          "rows": {
            "description": "Result rows, values rendered as text so a decimal, a date and a NULL all survive the wire.",
            "items": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "title": "Rows",
            "type": "array"
          },
          "saved_as": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The session view this statement was registered as, when it was. Every name in another receipt's ``views_used`` appears here on exactly one receipt, so the run's receipts define every view they cite.",
            "title": "Saved As"
          },
          "sql": {
            "description": "The statement as executed, verbatim.",
            "title": "Sql",
            "type": "string"
          },
          "table_bindings": {
            "description": "The tables this statement registered, each with the view name it was referenced by.",
            "items": {
              "$ref": "#/components/schemas/SqlTableBinding"
            },
            "title": "Table Bindings",
            "type": "array"
          },
          "truncated": {
            "default": false,
            "description": "Whether rows past the stored cap were cut from this receipt.",
            "title": "Truncated",
            "type": "boolean"
          },
          "view_sql": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The definition registered under `saved_as`, when it is not this statement itself. Null on an ordinary `save_as`, where `sql` IS the definition. Set by `build_journal_view`, which registers the per-journal frame and runs a bounded probe over it rather than materializing the whole frame — so the definition every later `views_used` refers to is still published by exactly one receipt.",
            "title": "View Sql"
          },
          "views_used": {
            "description": "Session views registered when this statement ran, in definition order — the registry snapshot it executed under. A statement naming a view is replayable only against these, which is what makes named views admissible where chaining a previous call's result handle is not.",
            "items": {
              "type": "string"
            },
            "title": "Views Used",
            "type": "array"
          },
          "warnings": {
            "description": "Pre-execution lint notes attached to this statement — non-blocking, and published as part of its working.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "result_id",
          "sql"
        ],
        "title": "SqlReceipt",
        "type": "object"
      },
      "SqlReplayReceipt": {
        "additionalProperties": false,
        "description": "Immutable inputs and engine identity for independent result recomputation.",
        "properties": {
          "catalog_sha256": {
            "description": "SHA-256 identity of the ordered source bindings used by this statement.",
            "pattern": "^[0-9a-f]{64}$",
            "title": "Catalog Sha256",
            "type": "string"
          },
          "engine": {
            "const": "duckdb",
            "description": "The query engine that executed the statement.",
            "title": "Engine",
            "type": "string"
          },
          "engine_threads": {
            "description": "DuckDB thread count used for this execution.",
            "exclusiveMinimum": 0.0,
            "title": "Engine Threads",
            "type": "integer"
          },
          "engine_version": {
            "description": "The query-engine version that executed the statement.",
            "title": "Engine Version",
            "type": "string"
          },
          "kind": {
            "description": "The verification lane appropriate for this statement.",
            "enum": [
              "aggregate",
              "rowset"
            ],
            "title": "Kind",
            "type": "string"
          },
          "logical_plan_sha256": {
            "description": "SHA-256 identity of the parser tree after source-position fields are removed.",
            "pattern": "^[0-9a-f]{64}$",
            "title": "Logical Plan Sha256",
            "type": "string"
          },
          "normalized_sql": {
            "description": "The normalized single SELECT statement to execute during independent replay.",
            "title": "Normalized Sql",
            "type": "string"
          },
          "result_artifact_sha256": {
            "description": "SHA-256 identity of the complete retained result Parquet produced by the service.",
            "pattern": "^[0-9a-f]{64}$",
            "title": "Result Artifact Sha256",
            "type": "string"
          },
          "result_data_sha256": {
            "description": "SHA-256 identity of the complete typed result rows.",
            "pattern": "^[0-9a-f]{64}$",
            "title": "Result Data Sha256",
            "type": "string"
          },
          "result_dependencies": {
            "description": "Earlier retained result handles read by this statement, in deterministic order.",
            "items": {
              "type": "string"
            },
            "title": "Result Dependencies",
            "type": "array"
          },
          "result_digest_version": {
            "description": "Versioned Arrow serialization scheme used for the typed-result identity.",
            "title": "Result Digest Version",
            "type": "string"
          },
          "schema_version": {
            "const": 1,
            "default": 1,
            "title": "Schema Version",
            "type": "integer"
          },
          "sql_sha256": {
            "description": "SHA-256 identity of the normalized statement.",
            "pattern": "^[0-9a-f]{64}$",
            "title": "Sql Sha256",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "engine",
          "engine_version",
          "engine_threads",
          "normalized_sql",
          "sql_sha256",
          "logical_plan_sha256",
          "catalog_sha256",
          "result_artifact_sha256",
          "result_data_sha256",
          "result_digest_version"
        ],
        "title": "SqlReplayReceipt",
        "type": "object"
      },
      "SqlTableBinding": {
        "additionalProperties": false,
        "description": "One table a receipted statement registered, in both namespaces at once.\n\n``path`` (plus ``component`` for one tab of a workbook) is the caller's own\nuploaded file; ``table_name`` is the view name the statement referenced it\nby. Both halves are load-bearing: view names are settled per run, so SQL\nthat hardcodes one is only replayable alongside the mapping that produced\nit — a statement published without its bindings cannot be re-run.",
        "properties": {
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The source worksheet, including when selected alone. Null for a direct upload or a historical unnamed tab.",
            "title": "Component"
          },
          "path": {
            "description": "The uploaded table file this view read, e.g. 'ledger/journal.xlsx'.",
            "title": "Path",
            "type": "string"
          },
          "source_sha256": {
            "anyOf": [
              {
                "pattern": "^[0-9a-f]{64}$",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "SHA-256 identity of the ingested source generation behind this table binding.",
            "title": "Source Sha256"
          },
          "table_name": {
            "description": "The view name the SQL referenced this table by, for THIS run.",
            "title": "Table Name",
            "type": "string"
          }
        },
        "required": [
          "path",
          "table_name"
        ],
        "title": "SqlTableBinding",
        "type": "object"
      },
      "StorageConnectionValidationResult": {
        "additionalProperties": false,
        "properties": {
          "connection_id": {
            "description": "Connection whose API and worker access was validated.",
            "format": "uuid",
            "title": "Connection Id",
            "type": "string"
          },
          "credential_generation": {
            "description": "Credential generation activated by this validation.",
            "title": "Credential Generation",
            "type": "integer"
          },
          "result_type": {
            "const": "storage_connection_validate",
            "default": "storage_connection_validate",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "connection_id",
          "credential_generation"
        ],
        "title": "StorageConnectionValidationResult",
        "type": "object"
      },
      "StructureProposal": {
        "additionalProperties": false,
        "properties": {
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              }
            ],
            "description": "Line-owned account column or ordered composite account identity.",
            "minLength": 1,
            "title": "Account"
          },
          "amount": {
            "description": "Amount basis to measure over the whole primary.",
            "discriminator": {
              "mapping": {
                "paired": "#/components/schemas/PairedAmount",
                "signed": "#/components/schemas/SignedAmount"
              },
              "propertyName": "kind"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/PairedAmount"
              },
              {
                "$ref": "#/components/schemas/SignedAmount"
              }
            ],
            "title": "Amount"
          },
          "effective_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional line-owned effective date column.",
            "title": "Effective Date"
          },
          "journal_key": {
            "description": "Ordered identity to measure, not an accepted key.",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "title": "Journal Key",
            "type": "array"
          },
          "line_ordinal": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional ordinal whose uniqueness is checked within each journal.",
            "title": "Line Ordinal"
          },
          "period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional period column; does not interpret its values.",
            "title": "Period"
          }
        },
        "required": [
          "journal_key",
          "amount",
          "account"
        ],
        "title": "StructureProposal",
        "type": "object"
      },
      "StructureRoleConflict": {
        "additionalProperties": false,
        "properties": {
          "allowed": {
            "const": false,
            "default": false,
            "description": "Whether this role combination is permitted.",
            "title": "Allowed",
            "type": "boolean"
          },
          "assigned_roles": {
            "description": "Conflicting semantic roles in proposal order.",
            "items": {
              "type": "string"
            },
            "title": "Assigned Roles",
            "type": "array"
          },
          "column": {
            "description": "Physical column assigned to incompatible structural roles.",
            "title": "Column",
            "type": "string"
          },
          "resolution": {
            "description": "Action that makes the structural nomination valid.",
            "title": "Resolution",
            "type": "string"
          }
        },
        "required": [
          "column",
          "assigned_roles",
          "resolution"
        ],
        "title": "StructureRoleConflict",
        "type": "object"
      },
      "SubdirectorySummary": {
        "additionalProperties": false,
        "description": "Orientation summary for one immediate subdirectory, covering its whole subtree.\n\nCarries enough to pick a descent target without listing the subtree: the\nfile count, the most-populous categories (capped at\nFOLDER_SUBDIR_TOP_CATEGORIES), and the failed-ingestion count when nonzero.",
        "properties": {
          "failed_files": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Files in the subtree with ingestion_status=failed; absent when none.",
            "title": "Failed Files"
          },
          "name": {
            "description": "The subfolder's name; append it to the described folder to descend.",
            "title": "Name",
            "type": "string"
          },
          "overall_files": {
            "description": "Files in the subfolder's whole subtree that the caller can see.",
            "title": "Overall Files",
            "type": "integer"
          },
          "top_categories": {
            "description": "The subtree's most common categories, most files first, capped.",
            "items": {
              "$ref": "#/components/schemas/CategoryCount"
            },
            "title": "Top Categories",
            "type": "array"
          }
        },
        "required": [
          "name",
          "overall_files"
        ],
        "title": "SubdirectorySummary",
        "type": "object"
      },
      "SuggestDomainDescriptionRequest": {
        "additionalProperties": false,
        "description": "Ask the model for a classifier-facing description of a named domain.",
        "properties": {
          "display_name": {
            "description": "The domain's display name. Meaningless names should yield an empty description.",
            "maxLength": 200,
            "minLength": 1,
            "title": "Display Name",
            "type": "string"
          }
        },
        "required": [
          "display_name"
        ],
        "title": "SuggestDomainDescriptionRequest",
        "type": "object"
      },
      "SuggestDomainDescriptionResponse": {
        "additionalProperties": false,
        "description": "Classifier-facing brief for taxonomy generation, or empty when the name is unusable.",
        "properties": {
          "description": {
            "description": "Suggested domain description for taxonomy generation. Empty when the name is not a recognizable subject.",
            "maxLength": 4000,
            "title": "Description",
            "type": "string"
          }
        },
        "required": [
          "description"
        ],
        "title": "SuggestDomainDescriptionResponse",
        "type": "object"
      },
      "SystemOneRequest": {
        "additionalProperties": false,
        "properties": {
          "questions": {
            "additionalProperties": {
              "discriminator": {
                "mapping": {
                  "choice": "#/components/schemas/ChoiceQuestion",
                  "noul": "#/components/schemas/NoulQuestion",
                  "score": "#/components/schemas/ScoreQuestion"
                },
                "propertyName": "type"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/NoulQuestion"
                },
                {
                  "$ref": "#/components/schemas/ChoiceQuestion"
                },
                {
                  "$ref": "#/components/schemas/ScoreQuestion"
                }
              ]
            },
            "description": "The questions to answer in one call, keyed by the name each answer returns under.",
            "maxProperties": 512,
            "minProperties": 1,
            "propertyNames": {
              "minLength": 1
            },
            "title": "Questions",
            "type": "object"
          },
          "state": {
            "$ref": "#/components/schemas/JsonValue",
            "description": "The situation to decide about: text, or any JSON value such as a record or a list of rows."
          }
        },
        "required": [
          "state",
          "questions"
        ],
        "title": "SystemOneRequest",
        "type": "object"
      },
      "SystemOneResponse": {
        "additionalProperties": false,
        "properties": {
          "answers": {
            "additionalProperties": {
              "discriminator": {
                "mapping": {
                  "choice": "#/components/schemas/ChoiceAnswer",
                  "noul": "#/components/schemas/NoulAnswer",
                  "score": "#/components/schemas/ScoreAnswer"
                },
                "propertyName": "type"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/NoulAnswer"
                },
                {
                  "$ref": "#/components/schemas/ChoiceAnswer"
                },
                {
                  "$ref": "#/components/schemas/ScoreAnswer"
                }
              ]
            },
            "description": "One answer per question, keyed by the question's name.",
            "title": "Answers",
            "type": "object"
          },
          "evaluation_time_ms": {
            "description": "Time the decision model spent on the call, in milliseconds.",
            "title": "Evaluation Time Ms",
            "type": "number"
          },
          "model": {
            "description": "The decision model that answered, as this deployment names it.",
            "title": "Model",
            "type": "string"
          },
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Correlation id of this request, the same one error bodies carry.",
            "title": "Request Id"
          },
          "usage": {
            "$ref": "#/components/schemas/SystemOneUsage",
            "description": "Token usage of the decision call, for cost tracking."
          }
        },
        "required": [
          "model",
          "answers",
          "usage",
          "evaluation_time_ms",
          "request_id"
        ],
        "title": "SystemOneResponse",
        "type": "object"
      },
      "SystemOneUsage": {
        "additionalProperties": false,
        "properties": {
          "input_tokens": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Tokens the decision model read, when the model reports them.",
            "title": "Input Tokens"
          },
          "output_tokens": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Tokens the decision model produced, when the model reports them.",
            "title": "Output Tokens"
          }
        },
        "required": [
          "input_tokens",
          "output_tokens"
        ],
        "title": "SystemOneUsage",
        "type": "object"
      },
      "TableCardWire": {
        "additionalProperties": false,
        "description": "One table as the stage reads it, with the grain figures a reader acts on.",
        "properties": {
          "columns": {
            "description": "Every column of the table, in the table's own column order.",
            "items": {
              "$ref": "#/components/schemas/ColumnCardWire"
            },
            "title": "Columns",
            "type": "array"
          },
          "component": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The worksheet or tab inside that file, where it has one.",
            "title": "Component"
          },
          "journal_key": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "The columns the accepted journal key is spelled over, or null when none qualified.",
            "title": "Journal Key"
          },
          "key_balanced_share": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Share of that key's groups netting to zero on the tested amount basis.",
            "title": "Key Balanced Share"
          },
          "key_median_lines": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Median lines per journal under that key.",
            "title": "Key Median Lines"
          },
          "line_shaped": {
            "description": "Whether this table is a journal-line file: a journal key and either a debit/credit pair or a live-measured signed amount.",
            "title": "Line Shaped",
            "type": "boolean"
          },
          "partition_family": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The family this table shares with its siblings when one ledger is split per period.",
            "title": "Partition Family"
          },
          "path": {
            "description": "The source file this table was ingested from.",
            "title": "Path",
            "type": "string"
          },
          "role": {
            "description": "What this table is in the package: journal_lines, journal_headers, trial_balance, chart_of_accounts, calendar, user_master, source_listing, or other.",
            "title": "Role",
            "type": "string"
          },
          "rows": {
            "description": "Rows in the table, as the ingest census counted them.",
            "title": "Rows",
            "type": "integer"
          },
          "table_name": {
            "description": "The name SQL over this workspace registers the table under.",
            "title": "Table Name",
            "type": "string"
          }
        },
        "required": [
          "path",
          "table_name",
          "role",
          "rows",
          "line_shaped",
          "columns"
        ],
        "title": "TableCardWire",
        "type": "object"
      },
      "TableQueryColumn": {
        "additionalProperties": false,
        "description": "One column of an executed SQL query's result preview.",
        "properties": {
          "data_type": {
            "title": "Data Type",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name",
          "data_type"
        ],
        "title": "TableQueryColumn",
        "type": "object"
      },
      "TableQueryGrounding": {
        "additionalProperties": false,
        "description": "One SQL query executed against the caller's tables while answering.\n\nThe grounding behind a computed evidence: when the agent answers a\ncount/sum/join question it runs a SQL agent over the uploaded tables, and\nthis is the receipt — the query text and a bounded preview of what it\nreturned. Attached to the evidence it grounds rather than published\nglobally, so a computed figure and its computation travel together.\n\n``source_paths`` name uploaded files, resolved server-side through the\ncaller's access gate exactly like ``source_path`` on the evidence itself.",
        "properties": {
          "columns": {
            "items": {
              "$ref": "#/components/schemas/TableQueryColumn"
            },
            "title": "Columns",
            "type": "array"
          },
          "grounding_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Qualification on grounding_status, when present. Set for 'unavailable' (explains why proof was not possible) and for 'exact' when capture succeeded but the source regions are broader than the minimal contributing set (e.g. 'regions_broad:narrowing_specs_unavailable'). None when grounding is fully exact or absent.",
            "title": "Grounding Reason"
          },
          "grounding_status": {
            "anyOf": [
              {
                "enum": [
                  "exact",
                  "unavailable",
                  "zero_result"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Capture-time provenance status behind this query's regions. 'exact': the exact-provenance sidecar proved every row the query read, so its 'provenance'-basis regions are trustworthy (source regions may be broader than the minimal contributing set when grounding_reason carries a 'regions_broad:…' qualifier). 'unavailable': no exact proof could be captured (a legacy result, or a statement shape the capturer cannot instrument) — no 'provenance'-basis regions are attached, never a guessed whole-table span. 'zero_result': the query matched no rows, so there is nothing to ground. None on legacy payloads and on a query with no unclaimed table left to ground.",
            "title": "Grounding Status"
          },
          "preview_truncated": {
            "default": false,
            "description": "Whether the preview cut rows or columns.",
            "title": "Preview Truncated",
            "type": "boolean"
          },
          "regions": {
            "description": "Original-file coordinates for the verified claims whose source file has an addressable grid.",
            "items": {
              "discriminator": {
                "mapping": {
                  "row_range": "#/components/schemas/RowRangeQueryRegion",
                  "sheet": "#/components/schemas/SheetQueryRegion"
                },
                "propertyName": "kind"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/SheetQueryRegion"
                },
                {
                  "$ref": "#/components/schemas/RowRangeQueryRegion"
                }
              ]
            },
            "title": "Regions",
            "type": "array"
          },
          "result_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Stable identity of the stored query result behind this receipt. Lets the grounding-rows endpoint replay this exact query for matched-row pages beyond the regions' inline runs.",
            "title": "Result Id"
          },
          "row_count": {
            "default": 0,
            "description": "Rows in the query's full result, not in the preview below.",
            "title": "Row Count",
            "type": "integer"
          },
          "rows": {
            "description": "Leading result rows, values rendered as text — a bounded preview, never the full result.",
            "items": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "title": "Rows",
            "type": "array"
          },
          "source_paths": {
            "description": "The uploaded table files this query read — directly, or through a prior result it built on — e.g. 'planning/FS GF Custom.xlsx'.",
            "items": {
              "type": "string"
            },
            "title": "Source Paths",
            "type": "array"
          },
          "sql": {
            "title": "Sql",
            "type": "string"
          },
          "supports_answer": {
            "default": true,
            "description": "False for exploratory SQL the tables engine ran but did not mark as part of the answer's calculation trail.",
            "title": "Supports Answer",
            "type": "boolean"
          },
          "verified": {
            "default": false,
            "description": "True when at least one claim behind this query passed mechanical verification against the source data. Independent of 'regions': a source without an addressable grid verifies but cannot be pointed at, so an empty 'regions' never means unverified.",
            "title": "Verified",
            "type": "boolean"
          }
        },
        "required": [
          "sql"
        ],
        "title": "TableQueryGrounding",
        "type": "object"
      },
      "TableRegion": {
        "additionalProperties": false,
        "description": "Rows and columns from a Parquet source, with reproducible SQL provenance.",
        "properties": {
          "columns": {
            "items": {
              "type": "string"
            },
            "title": "Columns",
            "type": "array"
          },
          "exact": {
            "title": "Exact",
            "type": "boolean"
          },
          "kind": {
            "const": "table_region",
            "default": "table_region",
            "title": "Kind",
            "type": "string"
          },
          "matched_rows": {
            "default": 0,
            "minimum": 0.0,
            "title": "Matched Rows",
            "type": "integer"
          },
          "row_ranges": {
            "items": {
              "$ref": "#/components/schemas/TableRowRange"
            },
            "title": "Row Ranges",
            "type": "array"
          },
          "source_file_name": {
            "title": "Source File Name",
            "type": "string"
          },
          "sql": {
            "title": "Sql",
            "type": "string"
          }
        },
        "required": [
          "source_file_name",
          "sql",
          "exact"
        ],
        "title": "TableRegion",
        "type": "object"
      },
      "TableRowRange": {
        "additionalProperties": false,
        "description": "Inclusive 0-based row range in a table source.",
        "properties": {
          "end": {
            "minimum": 0.0,
            "title": "End",
            "type": "integer"
          },
          "start": {
            "minimum": 0.0,
            "title": "Start",
            "type": "integer"
          }
        },
        "required": [
          "start",
          "end"
        ],
        "title": "TableRowRange",
        "type": "object"
      },
      "Taxonomy-Output": {
        "additionalProperties": false,
        "description": "The classification vocabulary.",
        "properties": {
          "allow_other": {
            "const": true,
            "default": true,
            "description": "Cannot be disabled: a document that fits nothing is labelled 'other', never force-fitted.",
            "title": "Allow Other",
            "type": "boolean"
          },
          "classes": {
            "items": {
              "$ref": "#/components/schemas/TaxonomyClass"
            },
            "maxItems": 400,
            "title": "Classes",
            "type": "array"
          }
        },
        "title": "Taxonomy",
        "type": "object"
      },
      "TaxonomyClass": {
        "additionalProperties": false,
        "description": "One leaf of the two-level taxonomy.\n\nThe two levels are ``group`` then ``subgroup`` — exactly two, which is what\nmakes a folder path predictable and a classification prompt short enough to\nbe accurate.",
        "properties": {
          "aliases": {
            "description": "Renames land here so old folder paths stay resolvable.",
            "items": {
              "type": "string"
            },
            "title": "Aliases",
            "type": "array"
          },
          "description": {
            "description": "Written for the classifier — it IS the prompt.",
            "title": "Description",
            "type": "string"
          },
          "group": {
            "maxLength": 64,
            "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
            "title": "Group",
            "type": "string"
          },
          "subgroup": {
            "maxLength": 64,
            "pattern": "^[a-z0-9]+(?:_[a-z0-9]+)*$",
            "title": "Subgroup",
            "type": "string"
          }
        },
        "required": [
          "group",
          "subgroup",
          "description"
        ],
        "title": "TaxonomyClass",
        "type": "object"
      },
      "Tenant": {
        "additionalProperties": false,
        "description": "One of the partner's child tenants. Send ``X-NDI-Tenant: ext:<external_ref>`` to act for it.",
        "properties": {
          "created_at": {
            "description": "When the tenant was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "data_retention": {
            "$ref": "#/components/schemas/GranularRetention",
            "description": "The data-retention setting in force for the tenant. Existing zero_retention tenants keep their policy when new Zero retention provisioning is disabled."
          },
          "disabled": {
            "description": "Whether the tenant is disabled. Its data is kept.",
            "title": "Disabled",
            "type": "boolean"
          },
          "display_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Human-readable name of the tenant.",
            "title": "Display Name"
          },
          "external_ref": {
            "description": "The partner's own reference for the tenant, unique per partner.",
            "title": "External Ref",
            "type": "string"
          },
          "id": {
            "description": "NDI's id for the tenant; X-NDI-Tenant accepts it too.",
            "format": "uuid",
            "title": "Id",
            "type": "string"
          },
          "limits": {
            "$ref": "#/components/schemas/TenantLimits",
            "description": "The limits in force for the tenant."
          }
        },
        "required": [
          "id",
          "external_ref",
          "display_name",
          "disabled",
          "limits",
          "data_retention",
          "created_at"
        ],
        "title": "Tenant",
        "type": "object"
      },
      "TenantBucketWorkspaceStorage": {
        "additionalProperties": false,
        "properties": {
          "location": {
            "description": "Workspace namespace in the tenant's configured bucket.",
            "title": "Location",
            "type": "string"
          },
          "provider": {
            "const": "s3",
            "default": "s3",
            "title": "Provider",
            "type": "string"
          },
          "type": {
            "const": "tenant_bucket",
            "default": "tenant_bucket",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "location"
        ],
        "title": "TenantBucketWorkspaceStorage",
        "type": "object"
      },
      "TenantLimits": {
        "additionalProperties": false,
        "description": "The limits in force for a tenant.",
        "properties": {
          "max_concurrent_jobs": {
            "description": "Parse, split, classify, categorize, extract, ground and agent jobs this tenant may have running at once; more wait in the queue. NDI's own per-tenant cap applies when it is lower.",
            "title": "Max Concurrent Jobs",
            "type": "integer"
          },
          "rpm": {
            "description": "Requests per minute this tenant may make.",
            "title": "Rpm",
            "type": "integer"
          }
        },
        "required": [
          "rpm",
          "max_concurrent_jobs"
        ],
        "title": "TenantLimits",
        "type": "object"
      },
      "TenantLimitsRequest": {
        "additionalProperties": false,
        "description": "Per-tenant limits a partner asks for; values above the partner's own caps are lowered to them.",
        "properties": {
          "max_concurrent_jobs": {
            "anyOf": [
              {
                "description": "Parse, split, classify, categorize, extract, ground and agent jobs this tenant may have running at once; more wait in the queue. NDI's own per-tenant cap applies when it is lower.",
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Concurrent Jobs"
          },
          "rpm": {
            "anyOf": [
              {
                "description": "Requests per minute this tenant may make.",
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rpm"
          }
        },
        "title": "TenantLimitsRequest",
        "type": "object"
      },
      "TenantPurgeJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "tenant_purge",
            "default": "tenant_purge",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TenantPurgeResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present once the purge has finished."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "TenantPurgeJob",
        "type": "object"
      },
      "TenantPurgeResult": {
        "additionalProperties": false,
        "description": "The tenant's content is gone; no row is deleted: its billing record and metadata rows stay, de-identified.\n\n``verified`` is true only when every store reports nothing remaining. An unfinished\ncancelled job counts against ``jobs`` and a workspace teardown that could not verify\nits own storage, index and graph counts against ``workspaces``. A purge that ends\nunverified is a ``succeeded`` job on purpose, like a workspace delete: the report says\nwhat is left, and a second DELETE re-runs it.",
        "properties": {
          "billing_record_kept": {
            "description": "True when the content-free billing record (job ids, kinds, timestamps, units, credits) was kept.",
            "title": "Billing Record Kept",
            "type": "boolean"
          },
          "external_ref": {
            "description": "The partner's own reference the tenant had. It stops resolving once the purge succeeds.",
            "title": "External Ref",
            "type": "string"
          },
          "result_type": {
            "const": "tenant_purge",
            "default": "tenant_purge",
            "title": "Result Type",
            "type": "string"
          },
          "stores": {
            "description": "One line per store, with what the verification pass still found.",
            "items": {
              "$ref": "#/components/schemas/TenantPurgeStoreReport"
            },
            "title": "Stores",
            "type": "array"
          },
          "tenant_id": {
            "description": "The tenant whose data was purged, as NDI identifies it.",
            "format": "uuid",
            "title": "Tenant Id",
            "type": "string"
          },
          "verified": {
            "description": "True when no content of the tenant remains anywhere and every kept metadata row is de-identified.",
            "title": "Verified",
            "type": "boolean"
          }
        },
        "required": [
          "tenant_id",
          "external_ref",
          "verified",
          "stores",
          "billing_record_kept"
        ],
        "title": "TenantPurgeResult",
        "type": "object"
      },
      "TenantPurgeStore": {
        "description": "One place tenant data lives, and so one line of a purge's verification report.\n\nA purge never deletes a Postgres row: each store's rows are emptied or de-identified and marked deleted, and\nonly stored objects and Redis keys are removed.",
        "enum": [
          "jobs",
          "workspaces",
          "files",
          "upload_sessions",
          "profile_cache",
          "answer_cache",
          "catalog",
          "ledger_decisions",
          "parse_exports",
          "webhooks",
          "api_keys",
          "members",
          "users",
          "cli_sessions",
          "limit_overrides",
          "schemas_and_labels",
          "perception_cache",
          "storage",
          "redis"
        ],
        "title": "TenantPurgeStore",
        "type": "string"
      },
      "TenantPurgeStoreReport": {
        "additionalProperties": false,
        "description": "What the verification pass still finds of the tenant in one store.",
        "properties": {
          "remaining": {
            "description": "Rows that still hold the tenant's content or identifying data or still grant access, objects, and open executions still found there. Kept rows that are already emptied do not count. Zero when clean.",
            "minimum": 0.0,
            "title": "Remaining",
            "type": "integer"
          },
          "store": {
            "$ref": "#/components/schemas/TenantPurgeStore",
            "description": "The store this line reports."
          }
        },
        "required": [
          "store",
          "remaining"
        ],
        "title": "TenantPurgeStoreReport",
        "type": "object"
      },
      "TextCell": {
        "additionalProperties": false,
        "properties": {
          "kind": {
            "const": "text",
            "default": "text",
            "title": "Kind",
            "type": "string"
          },
          "text": {
            "title": "Text",
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "title": "TextCell",
        "type": "object"
      },
      "TextRange": {
        "additionalProperties": false,
        "description": "A character span in a derivative's text, with the page(s) it falls on.\n\n``pages`` is every page the span overlaps — a chunk that straddles a page\nmarker belongs to both, and a reader handed only the first would miss the\npart of the span that carries the match. ``page`` is the first of them,\nkept because most producers and consumers only ever deal in one page.",
        "properties": {
          "char_end": {
            "title": "Char End",
            "type": "integer"
          },
          "char_start": {
            "title": "Char Start",
            "type": "integer"
          },
          "kind": {
            "const": "text_range",
            "default": "text_range",
            "title": "Kind",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Page"
          },
          "pages": {
            "items": {
              "type": "integer"
            },
            "title": "Pages",
            "type": "array"
          }
        },
        "required": [
          "char_start",
          "char_end"
        ],
        "title": "TextRange",
        "type": "object"
      },
      "TextSpan": {
        "additionalProperties": false,
        "description": "A character span in derived text (optional page when known).",
        "properties": {
          "char_end": {
            "description": "Exclusive end offset in the derived text.",
            "minimum": 0.0,
            "title": "Char End",
            "type": "integer"
          },
          "char_start": {
            "description": "Inclusive start offset in the derived text.",
            "minimum": 0.0,
            "title": "Char Start",
            "type": "integer"
          },
          "kind": {
            "const": "text_span",
            "default": "text_span",
            "title": "Kind",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "1-based page when the span maps to a known page. Null for text-only sources.",
            "title": "Page"
          }
        },
        "required": [
          "char_start",
          "char_end"
        ],
        "title": "TextSpan",
        "type": "object"
      },
      "ToolCallTrace": {
        "additionalProperties": false,
        "description": "Carries an argument digest rather than raw arguments.\n\nRaw arguments would be a side channel around ``Coverage``: a caller could\nread back what the loop searched for on its behalf.",
        "properties": {
          "arguments_digest": {
            "title": "Arguments Digest",
            "type": "string"
          },
          "duration_ms": {
            "title": "Duration Ms",
            "type": "integer"
          },
          "hits": {
            "title": "Hits",
            "type": "integer"
          },
          "tool": {
            "title": "Tool",
            "type": "string"
          }
        },
        "required": [
          "tool",
          "arguments_digest",
          "hits",
          "duration_ms"
        ],
        "title": "ToolCallTrace",
        "type": "object"
      },
      "TruncationTarget": {
        "description": "Processing area where content was reduced before producing a result.",
        "enum": [
          "classification_input",
          "document_content",
          "spreadsheet_region",
          "extraction_array"
        ],
        "title": "TruncationTarget",
        "type": "string"
      },
      "TruncationUnit": {
        "description": "Unit used to quantify a content reduction.",
        "enum": [
          "characters",
          "tokens",
          "rows",
          "columns",
          "cells",
          "items"
        ],
        "title": "TruncationUnit",
        "type": "string"
      },
      "UnavailableTable": {
        "additionalProperties": false,
        "description": "A requested path (or one of its ingested sheets) that could not be queried.\n\n``error_kind`` is ``None`` only when the failure happened before ingest\ncould even classify it (an access or resolution error, which raises as a\ntyped HTTP error instead of reaching this list).\n\nLives here rather than beside the tool responses because a stored job\nresult reports the same unusable inputs the synchronous response did — one\ndefinition, so a reopened run cannot describe them differently.",
        "properties": {
          "error": {
            "title": "Error",
            "type": "string"
          },
          "error_kind": {
            "anyOf": [
              {
                "enum": [
                  "conversion_rejected",
                  "conversion_failed",
                  "profile_rejected",
                  "profile_failed"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error Kind"
          },
          "path": {
            "title": "Path",
            "type": "string"
          }
        },
        "required": [
          "path",
          "error"
        ],
        "title": "UnavailableTable",
        "type": "object"
      },
      "UpdateAccessLabelRequest": {
        "additionalProperties": false,
        "description": "Partial update. Name changes are refused — rename by delete + create.",
        "properties": {
          "description": {
            "anyOf": [
              {
                "maxLength": 2000,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          }
        },
        "title": "UpdateAccessLabelRequest",
        "type": "object"
      },
      "UpdateDomainRequest": {
        "additionalProperties": false,
        "description": "Any subset of the create request.\n\nEditing a ``draft`` mutates it. Editing a ``published`` domain creates\nversion *n+1* as a new draft and leaves version *n* untouched — there is no\nway to change the vocabulary under a live corpus, because a workspace that\ncould not explain its own folder structure is worse than one with an old\nvocabulary.",
        "properties": {
          "display_name": {
            "anyOf": [
              {
                "maxLength": 200,
                "minLength": 1,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Display Name"
          },
          "taxonomy": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ndi_service__app__platform_api__domains__schemas__Taxonomy"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "title": "UpdateDomainRequest",
        "type": "object"
      },
      "UpdateJobRequest": {
        "additionalProperties": false,
        "description": "Body for ``PATCH /jobs/{job_id}``.\n\n``name`` is the only mutable caller-facing field on a job — everything else\nis either the frozen request or worker-owned state. An explicit ``null``\nclears the custom name; public document runs then display their stable server fallback.",
        "properties": {
          "name": {
            "anyOf": [
              {
                "maxLength": 200,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "title": "UpdateJobRequest",
        "type": "object"
      },
      "UpdateWorkspaceRequest": {
        "additionalProperties": false,
        "description": "Change a workspace's mutable configuration.\n\nPresence-aware: a field omitted from the body is left exactly as it is, so a\ncaller changing one block cannot clear another by not mentioning it. A field\nthat *is* supplied replaces its block whole — the rule ``set_key_grants``\nfollows for label grants, which is what keeps turning a policy off the same\noperation as turning it on, with no add/remove asymmetry to get wrong.\n\nThe display name of an ordinary workspace (platform-provisioned names stay fixed),\nthe knowledge-graph, currency and ledger-understanding policies and the global\ncontext are mutable. The domain and the label list are not: both are part of the versioned config\nrecord that every derived artifact is stamped with, so editing them in place\nwould silently re-describe material that was derived under the old one.",
        "properties": {
          "currency": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CurrencyPolicy"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace's complete new currency-reading policy, or omitted to leave it unchanged. Whole-block like ``knowledge_graph``: an empty object resets to the USD default, and ``{\"default\": null}`` is how the policy is cleared to assume nothing. Applies from the next ingestion onwards: amounts already extracted as ambiguous stay that way until their file is re-ingested, since the catalog records what a past extraction could read."
          },
          "global_context": {
            "anyOf": [
              {
                "maxLength": 20000,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace's new global context, or omitted to leave it unchanged; `\"\"` clears it. Standing background for every query in this workspace — how its journals are keyed, which entity it covers, what an auditor already knows. A je-testing or search request that omits `context` runs with this text; a request that sends `context` replaces it for that run, and `\"\"` runs with none. Empty means none. Surrounding whitespace is stripped.",
            "title": "Global Context"
          },
          "knowledge_graph": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/KnowledgeGraphConfig"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace's complete new knowledge-graph policy, or omitted to leave it unchanged. Supplying it replaces every field it holds, so send the block read back from the workspace with your edits applied rather than only the key you are changing."
          },
          "ledger_understanding": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LedgerUnderstandingConfig"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace's complete new ledger-understanding policy, or omitted to leave it unchanged. Whole-block like ``knowledge_graph``. Turning the trigger off stops future ingestions chaining a run; it never refuses an explicit one, and it does not withdraw a report already measured."
          },
          "name": {
            "description": "New display name for an ordinary workspace. Platform-provisioned names are fixed. Omit to keep the current name; null is not accepted.",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          }
        },
        "title": "UpdateWorkspaceRequest",
        "type": "object"
      },
      "UploadFileJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "file_upload",
            "default": "file_upload",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UploadFileResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "UploadFileJob",
        "type": "object"
      },
      "UploadFileResult": {
        "additionalProperties": false,
        "description": "Also the result of ``JobKind.UPLOAD_SESSION_COMPLETE``.\n\nA chunked upload's completion produces exactly this shape — the file it\nlanded, and whether it deduplicated — so it deliberately reuses this\nresult rather than minting a near-identical discriminated variant whose\n``result_type`` would just be a second name for the same two fields.",
        "properties": {
          "deduplicated": {
            "description": "Identical bytes were already present.",
            "title": "Deduplicated",
            "type": "boolean"
          },
          "file": {
            "$ref": "#/components/schemas/File"
          },
          "result_type": {
            "const": "file_upload",
            "default": "file_upload",
            "title": "Result Type",
            "type": "string"
          }
        },
        "required": [
          "file",
          "deduplicated"
        ],
        "title": "UploadFileResult",
        "type": "object"
      },
      "UploadGrantResponse": {
        "additionalProperties": false,
        "description": "A minted upload grant, ready to hand to an end client.\n\nThe holder sends ``token`` in the ``X-Upload-Token`` header of a multipart\n``POST`` to ``upload_url`` (the workspace's ``upload_file`` route). The\ngrant authorizes that one method only, and is single-use where the\ndeployment runs Redis.",
        "properties": {
          "expires_at": {
            "description": "When the grant stops verifying.",
            "format": "date-time",
            "title": "Expires At",
            "type": "string"
          },
          "token": {
            "description": "Send in the X-Upload-Token header of the upload request.",
            "title": "Token",
            "type": "string"
          },
          "upload_url": {
            "description": "The upload_file route the token is valid against.",
            "title": "Upload Url",
            "type": "string"
          }
        },
        "required": [
          "token",
          "upload_url",
          "expires_at"
        ],
        "title": "UploadGrantResponse",
        "type": "object"
      },
      "UploadSessionCompleteJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "upload_session_complete",
            "default": "upload_session_complete",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UploadFileResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "UploadSessionCompleteJob",
        "type": "object"
      },
      "UploadSessionPart": {
        "additionalProperties": false,
        "description": "One landed part, as reported by ``GET .../upload-sessions/{session_id}``.",
        "properties": {
          "part_number": {
            "title": "Part Number",
            "type": "integer"
          },
          "size_bytes": {
            "title": "Size Bytes",
            "type": "integer"
          }
        },
        "required": [
          "part_number",
          "size_bytes"
        ],
        "title": "UploadSessionPart",
        "type": "object"
      },
      "UploadSessionPartResponse": {
        "additionalProperties": false,
        "description": "Result of ``PUT .../upload-sessions/{session_id}/parts/{part_number}``.",
        "properties": {
          "part_number": {
            "title": "Part Number",
            "type": "integer"
          },
          "size_bytes": {
            "description": "Bytes actually received for this part.",
            "title": "Size Bytes",
            "type": "integer"
          }
        },
        "required": [
          "part_number",
          "size_bytes"
        ],
        "title": "UploadSessionPartResponse",
        "type": "object"
      },
      "UploadSessionStatusResponse": {
        "additionalProperties": false,
        "description": "Result of ``GET .../upload-sessions/{session_id}`` — for resuming after a drop.\n\nA resuming client diffs ``parts`` against what it already sent and PUTs\nonly what is missing; it never needs to re-derive part numbers itself.",
        "properties": {
          "chunk_size": {
            "title": "Chunk Size",
            "type": "integer"
          },
          "declared_size_bytes": {
            "title": "Declared Size Bytes",
            "type": "integer"
          },
          "expires_at": {
            "format": "date-time",
            "title": "Expires At",
            "type": "string"
          },
          "parts": {
            "description": "Parts landed so far, unordered.",
            "items": {
              "$ref": "#/components/schemas/UploadSessionPart"
            },
            "title": "Parts",
            "type": "array"
          },
          "received_bytes": {
            "description": "Sum of parts[*].size_bytes.",
            "title": "Received Bytes",
            "type": "integer"
          },
          "session_id": {
            "format": "uuid",
            "title": "Session Id",
            "type": "string"
          },
          "status": {
            "enum": [
              "open",
              "completing",
              "completed",
              "aborted"
            ],
            "title": "Status",
            "type": "string"
          },
          "total_parts": {
            "title": "Total Parts",
            "type": "integer"
          }
        },
        "required": [
          "session_id",
          "status",
          "chunk_size",
          "total_parts",
          "parts",
          "received_bytes",
          "declared_size_bytes",
          "expires_at"
        ],
        "title": "UploadSessionStatusResponse",
        "type": "object"
      },
      "UploadSource": {
        "additionalProperties": false,
        "description": "Bytes staged through ``POST /v1/uploads``. Retained until explicit deletion, except under Zero retention.",
        "properties": {
          "type": {
            "const": "upload",
            "default": "upload",
            "title": "Type",
            "type": "string"
          },
          "upload_id": {
            "description": "Id returned by POST /v1/uploads. Ordinary bytes remain until their consuming jobs or tenant are deleted.",
            "format": "uuid",
            "title": "Upload Id",
            "type": "string"
          }
        },
        "required": [
          "upload_id"
        ],
        "title": "UploadSource",
        "type": "object"
      },
      "UrlSource": {
        "additionalProperties": false,
        "description": "A public or presigned HTTPS location we fetch server-side.",
        "properties": {
          "file_name": {
            "description": "Filename to record for the fetched bytes.",
            "maxLength": 512,
            "title": "File Name",
            "type": "string"
          },
          "type": {
            "const": "url",
            "default": "url",
            "title": "Type",
            "type": "string"
          },
          "url": {
            "description": "HTTPS URL the service fetches.",
            "maxLength": 2048,
            "pattern": "^https://",
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "url",
          "file_name"
        ],
        "title": "UrlSource",
        "type": "object"
      },
      "UsageBucket": {
        "additionalProperties": false,
        "description": "One aggregation bucket returned by ``GET /usage``.\n\n``credits`` is what the bill charges. The admission allowance also counts measured failed and cancelled work and\nin-flight reservations, so a ``quota_exceeded`` ``credits_used`` can exceed these credits.",
        "properties": {
          "bytes_ingested": {
            "title": "Bytes Ingested",
            "type": "integer"
          },
          "credits": {
            "description": "Final credits of the jobs in this bucket whose usage is final. What a bill charges.",
            "title": "Credits",
            "type": "integer"
          },
          "jobs": {
            "title": "Jobs",
            "type": "integer"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "pages": {
            "title": "Pages",
            "type": "integer"
          },
          "unfinalized_jobs": {
            "description": "Jobs in this bucket whose usage is not final yet, so they are not in `credits`.",
            "title": "Unfinalized Jobs",
            "type": "integer"
          },
          "units": {
            "title": "Units",
            "type": "integer"
          }
        },
        "required": [
          "key",
          "units",
          "jobs",
          "pages",
          "bytes_ingested",
          "credits",
          "unfinalized_jobs"
        ],
        "title": "UsageBucket",
        "type": "object"
      },
      "UsageLine": {
        "additionalProperties": false,
        "description": "One part of a job's final credits.",
        "properties": {
          "credits": {
            "description": "quantity x credits_per_unit x multiplier: what this part added to the job's credits. 0 when waived or included in the ordinary price.",
            "minimum": 0.0,
            "title": "Credits",
            "type": "integer"
          },
          "credits_per_unit": {
            "description": "The credit schedule's rate for one unit of this part; zero for OCR included in the ordinary price.",
            "minimum": 0.0,
            "title": "Credits Per Unit",
            "type": "integer"
          },
          "multiplier": {
            "description": "2 on the parse and image_ocr parts of a parse_mode \"high\" job, otherwise 1.",
            "minimum": 1.0,
            "title": "Multiplier",
            "type": "integer"
          },
          "part": {
            "description": "parse: reading the document into text. operation: the tool's own work on what was parsed. image_ocr: reading the images inside an email, HTML or spreadsheet file. A ground job's image_ocr is the email images it read to find targets its text search missed.",
            "enum": [
              "parse",
              "operation",
              "image_ocr"
            ],
            "title": "Part",
            "type": "string"
          },
          "quantity": {
            "description": "How many units of work this part measured, including waived or included work.",
            "minimum": 0.0,
            "title": "Quantity",
            "type": "integer"
          },
          "unit": {
            "description": "What quantity counts: page is a page or page-equivalent (a spreadsheet's non-empty cells, a minute of audio), item is a ground item, image is an image Parse read inside an email, HTML or spreadsheet file, unit is a job priced by its units directly (agent steps).",
            "enum": [
              "page",
              "item",
              "unit",
              "image"
            ],
            "title": "Unit",
            "type": "string"
          },
          "waiver": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/UsageWaiver"
              },
              {
                "type": "null"
              }
            ],
            "description": "Verified reuse that waived this work. Null for charged work and for included OCR without reuse."
          }
        },
        "required": [
          "part",
          "quantity",
          "unit",
          "credits_per_unit",
          "multiplier",
          "credits"
        ],
        "title": "UsageLine",
        "type": "object"
      },
      "UsageOverviewPoint": {
        "additionalProperties": false,
        "description": "One calendar day in the usage-overview series.",
        "properties": {
          "day": {
            "format": "date",
            "title": "Day",
            "type": "string"
          },
          "documents": {
            "title": "Documents",
            "type": "integer"
          }
        },
        "required": [
          "day",
          "documents"
        ],
        "title": "UsageOverviewPoint",
        "type": "object"
      },
      "UsageOverviewResponse": {
        "additionalProperties": false,
        "description": "Dashboard figures for a rolling ``7d`` / ``30d`` / ``90d`` window.\n\nPrior-period fields are the same-length window immediately before\n``period_start``. The frontend derives the percentage / delta; this\nresponse only reports the two raw values. Average processing time is\n``null`` when the window has no succeeded document-operation jobs.",
        "properties": {
          "active_jobs": {
            "title": "Active Jobs",
            "type": "integer"
          },
          "avg_processing_seconds": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Avg Processing Seconds"
          },
          "avg_processing_seconds_prior": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Avg Processing Seconds Prior"
          },
          "documents_processed": {
            "title": "Documents Processed",
            "type": "integer"
          },
          "documents_processed_prior": {
            "title": "Documents Processed Prior",
            "type": "integer"
          },
          "period_end": {
            "format": "date",
            "title": "Period End",
            "type": "string"
          },
          "period_start": {
            "format": "date",
            "title": "Period Start",
            "type": "string"
          },
          "queued_jobs": {
            "title": "Queued Jobs",
            "type": "integer"
          },
          "series": {
            "items": {
              "$ref": "#/components/schemas/UsageOverviewPoint"
            },
            "title": "Series",
            "type": "array"
          },
          "window": {
            "enum": [
              "7d",
              "30d",
              "90d"
            ],
            "title": "Window",
            "type": "string"
          }
        },
        "required": [
          "window",
          "period_start",
          "period_end",
          "documents_processed",
          "documents_processed_prior",
          "active_jobs",
          "queued_jobs",
          "avg_processing_seconds",
          "avg_processing_seconds_prior",
          "series"
        ],
        "title": "UsageOverviewResponse",
        "type": "object"
      },
      "UsageWaiver": {
        "additionalProperties": false,
        "description": "Why part of a job, or the whole job, was not charged.",
        "properties": {
          "part": {
            "description": "parse: the parse part was not charged. job: nothing in the job was charged.",
            "enum": [
              "parse",
              "job"
            ],
            "title": "Part",
            "type": "string"
          },
          "reason": {
            "description": "reused_parse: the job read a parse your earlier job already paid for. repeat_of_job: the job repeated your earlier job exactly and was answered with its result.",
            "enum": [
              "reused_parse",
              "repeat_of_job"
            ],
            "title": "Reason",
            "type": "string"
          },
          "source_job_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Always null: billing history must not disclose another job as its visibility changes.",
            "title": "Source Job Id"
          }
        },
        "required": [
          "part",
          "reason"
        ],
        "title": "UsageWaiver",
        "type": "object"
      },
      "ValueCountWire": {
        "additionalProperties": false,
        "description": "One value of a column's domain and how many rows carry it.",
        "properties": {
          "rows": {
            "description": "Rows carrying this value, as the census counted them.",
            "title": "Rows",
            "type": "integer"
          },
          "value": {
            "description": "The value as the column spells it, rendered as text.",
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "value",
          "rows"
        ],
        "title": "ValueCountWire",
        "type": "object"
      },
      "VisualRegion": {
        "additionalProperties": false,
        "properties": {
          "bbox": {
            "maxItems": 4,
            "minItems": 4,
            "prefixItems": [
              {
                "type": "number"
              },
              {
                "type": "number"
              },
              {
                "type": "number"
              },
              {
                "type": "number"
              }
            ],
            "title": "Bbox",
            "type": "array"
          },
          "kind": {
            "const": "visual_region",
            "default": "visual_region",
            "title": "Kind",
            "type": "string"
          },
          "page": {
            "title": "Page",
            "type": "integer"
          }
        },
        "required": [
          "page",
          "bbox"
        ],
        "title": "VisualRegion",
        "type": "object"
      },
      "WordAnchor": {
        "additionalProperties": false,
        "description": "Native OOXML paragraph span, independent of converted-PDF pagination.",
        "properties": {
          "char_end": {
            "description": "Exclusive code-point offset in the same paragraph text.",
            "exclusiveMinimum": 0.0,
            "title": "Char End",
            "type": "integer"
          },
          "char_start": {
            "description": "Inclusive code-point offset in visible paragraph text: w:t runs joined with tabs and breaks.",
            "minimum": 0.0,
            "title": "Char Start",
            "type": "integer"
          },
          "paragraph_index": {
            "description": "Zero-based w:p index in this part, counting start tags including table-cell paragraphs.",
            "minimum": 0.0,
            "title": "Paragraph Index",
            "type": "integer"
          },
          "part": {
            "description": "OOXML package member containing the matched paragraph.",
            "pattern": "^word/(?:document|header\\d+|footer\\d+|footnotes|endnotes)\\.xml$",
            "title": "Part",
            "type": "string"
          }
        },
        "required": [
          "part",
          "paragraph_index",
          "char_start",
          "char_end"
        ],
        "title": "WordAnchor",
        "type": "object"
      },
      "Workspace": {
        "additionalProperties": false,
        "description": "A provisioned workspace, as the API returns it.\n\nStorage metadata identifies the durable backend without exposing credentials.",
        "properties": {
          "access": {
            "$ref": "#/components/schemas/AccessConfig"
          },
          "config_version": {
            "title": "Config Version",
            "type": "integer"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "currency": {
            "$ref": "#/components/schemas/CurrencyPolicy"
          },
          "domain_id": {
            "format": "uuid",
            "title": "Domain Id",
            "type": "string"
          },
          "domain_slug": {
            "title": "Domain Slug",
            "type": "string"
          },
          "domain_version": {
            "title": "Domain Version",
            "type": "integer"
          },
          "global_context": {
            "default": "",
            "description": "Standing background for every query in this workspace — how its journals are keyed, which entity it covers, what an auditor already knows. A je-testing or search request that omits `context` runs with this text; a request that sends `context` replaces it for that run, and `\"\"` runs with none. Empty means none. Surrounding whitespace is stripped.",
            "title": "Global Context",
            "type": "string"
          },
          "knowledge_graph": {
            "$ref": "#/components/schemas/KnowledgeGraphConfig"
          },
          "ledger_understanding": {
            "$ref": "#/components/schemas/LedgerUnderstandingConfig",
            "description": "When this workspace understands its general ledger — table and column roles, the journal key and its balance proof, and the integrity battery. A workspace configured before this block existed reads back the default."
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "owner_user_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The console user who owns the workspace, or null for an organization-owned integration workspace.",
            "title": "Owner User Id"
          },
          "purpose": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WorkspacePurpose"
              },
              {
                "type": "null"
              }
            ],
            "description": "Set when the platform provisioned this workspace on a person's behalf rather than at a caller's request. Such a workspace cannot be deleted. Null for every workspace created through this API."
          },
          "share_count": {
            "description": "Number of users explicitly granted workspace access; excludes the owner.",
            "minimum": 0.0,
            "title": "Share Count",
            "type": "integer"
          },
          "status": {
            "$ref": "#/components/schemas/WorkspaceStatus"
          },
          "storage": {
            "description": "The workspace's durable storage backend and external connection health.",
            "discriminator": {
              "mapping": {
                "external": "#/components/schemas/ExternalWorkspaceStorage",
                "managed": "#/components/schemas/ManagedWorkspaceStorage",
                "tenant_bucket": "#/components/schemas/TenantBucketWorkspaceStorage"
              },
              "propertyName": "type"
            },
            "oneOf": [
              {
                "$ref": "#/components/schemas/ManagedWorkspaceStorage"
              },
              {
                "$ref": "#/components/schemas/TenantBucketWorkspaceStorage"
              },
              {
                "$ref": "#/components/schemas/ExternalWorkspaceStorage"
              }
            ],
            "title": "Storage"
          },
          "updated_at": {
            "format": "date-time",
            "title": "Updated At",
            "type": "string"
          },
          "workspace_id": {
            "format": "uuid",
            "title": "Workspace Id",
            "type": "string"
          }
        },
        "required": [
          "workspace_id",
          "owner_user_id",
          "share_count",
          "name",
          "domain_id",
          "domain_slug",
          "domain_version",
          "access",
          "knowledge_graph",
          "currency",
          "config_version",
          "status",
          "created_at",
          "updated_at"
        ],
        "title": "Workspace",
        "type": "object"
      },
      "WorkspaceDeleteJob": {
        "additionalProperties": false,
        "properties": {
          "cost": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobCost"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final USD component prices under the sheet pinned at acceptance; null before finalization or when no dollar sheet was configured. Does not change legacy credit billing."
          },
          "created_at": {
            "description": "When the job row was created.",
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "credit_schedule_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version of the credit schedule `credits` were priced under. Null until `usage_final` is true.",
            "title": "Credit Schedule Version"
          },
          "credits": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Final credits billed for this job, priced once under `credit_schedule_version`. Null until `usage_final` is true. Never changes afterwards, including after payload expiry or deletion. Failed and cancelled-before-completion jobs finalize with 0 credits, including delivered parts; ones finalized before that policy keep their credits. Always null on a stage job that Automatic Search delegated: its work is billed on the parent job.",
            "title": "Credits"
          },
          "deleted_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the caller hid this run from listings, via `delete_job`. A soft delete: the job still reads by id and still counts toward `GET /v1/usage` — what it stops doing is appearing in `GET /v1/jobs`.",
            "title": "Deleted At"
          },
          "effort": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "How hard this run worked, for the search kinds that carry it. A deep-search job (kind deep_search_v2) created before the effort knob was removed echoes its requested level: 'low', 'medium', or 'high'; newer deep-search jobs, which all run one configuration, read null. An intelligent_search row carries an internal selector instead: 'fast' is fact-search, 'automatic' is automatic-search, and 'deep' (or the legacy 'balanced') is a deep-search or console QA chat job created before the 2026-09 consolidation — those two are not distinguishable by this field. Null for every other kind. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Effort"
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Typed failure envelope when status is failed. Null on any other status, and while result_error withholds content."
          },
          "finished_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the job reached a terminal status.",
            "title": "Finished At"
          },
          "force": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request's own `force` flag, echoed regardless of outcome. Present for kinds whose request carries one (e.g. kg_build, where a true value cleared the durable store before the job ran) so a caller can tell that apart from a build that failed leaving the prior store untouched — `result` alone cannot, since it is absent on failure either way.",
            "title": "Force"
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Key that was replayed to return this job. Absent when the create call had no Idempotency-Key.",
            "title": "Idempotency Key"
          },
          "job_id": {
            "description": "Server-minted id. Poll GET /v1/jobs/{job_id} or pass wait_seconds on create.",
            "format": "uuid",
            "title": "Job Id",
            "type": "string"
          },
          "kind": {
            "const": "workspace_delete",
            "default": "workspace_delete",
            "title": "Kind",
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Display name (the console's 'project'). Public Parse, Split, Classify, Extract, and Ground runs supply a stable server default when blank; citation-generated Ground jobs are excluded. mutable via PATCH /v1/jobs/{job_id}.",
            "title": "Name"
          },
          "payload_expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cleanup deadline after explicit deletion. Null for retained content; Zero retention uses its delivery window.",
            "title": "Payload Expires At"
          },
          "progress": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobProgress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Live progress while the job is running. Null while queued and after the job finishes."
          },
          "project_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Caller-minted grouping id shared by jobs submitted together. Filterable on GET /v1/jobs.",
            "title": "Project Id"
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The question this job was asked, for the search kinds that carry one (intelligent_search, qa_file, qa_tables, filtered_search); null for every other kind. Read from the stored request, so it rides the same retention path as `result`: null once `result_state` leaves `available`. Narrow by design — the frozen access context never reaches the wire. File scope is summarised separately as `query_scope`.",
            "title": "Query"
          },
          "query_scope": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "file": "#/components/schemas/FileQueryScope",
                    "files": "#/components/schemas/FilesQueryScope",
                    "path_prefix": "#/components/schemas/PathPrefixQueryScope",
                    "workspace": "#/components/schemas/WorkspaceQueryScope"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/WorkspaceQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FileQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/PathPrefixQueryScope"
                  },
                  {
                    "$ref": "#/components/schemas/FilesQueryScope"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "Where this search ran, summarised for history UIs: the whole workspace, one file path, one folder prefix, or a count of files. Null for non-query jobs, filtered-search page continuations, and once `result_state` leaves `available`. Never lists multiple filenames, never the raw request, and never the frozen API-key id.",
            "title": "Query Scope"
          },
          "replayed": {
            "default": false,
            "description": "True only on an idempotent replay response. No new charge is made; credits remains the original job's cost.",
            "title": "Replayed",
            "type": "boolean"
          },
          "result": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WorkspaceDeleteResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "Present only on succeeded, and only while retained."
          },
          "result_error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Error"
              },
              {
                "type": "null"
              }
            ],
            "description": "Current storage refusal withholding content. Separate from the recorded job outcome; cleared when access returns."
          },
          "result_state": {
            "$ref": "#/components/schemas/ResultState",
            "default": "available",
            "description": "Why result may be null. storage_unavailable means its workspace binding currently refuses content access; available with a null result means the job has not succeeded yet; expired and not_retained mean the payload was dropped by retention; cancelled means the job, or the job it ran for, was cancelled, so no result is served (a job cancelled before completion is not charged)."
          },
          "source": {
            "anyOf": [
              {
                "discriminator": {
                  "mapping": {
                    "parse_result": "#/components/schemas/ParseResultSource",
                    "upload": "#/components/schemas/UploadSource",
                    "url": "#/components/schemas/UrlSource",
                    "workspace_file": "#/components/schemas/WorkspaceFileSource"
                  },
                  "propertyName": "type"
                },
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/UploadSource"
                  },
                  {
                    "$ref": "#/components/schemas/UrlSource"
                  },
                  {
                    "$ref": "#/components/schemas/WorkspaceFileSource"
                  },
                  {
                    "$ref": "#/components/schemas/ParseResultSource"
                  }
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What this job read, for the document operations that take a single `source` (parse, split, classify, extract, ground); null for every other kind. Together with `workspace_id` this is what lets a caller re-open the document a past run was about — both `workspace_file` and `upload` sources remain until explicit deletion. Read from the stored request, so it rides the same retention path as `query` and `result`: null once `result_state` leaves `available`.",
            "title": "Source"
          },
          "started_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When execution began. Null while still queued.",
            "title": "Started At"
          },
          "status": {
            "$ref": "#/components/schemas/ndi_service__app__platform_api__contracts__JobStatus",
            "description": "Lifecycle: queued, running, succeeded, failed, or cancelled."
          },
          "surface": {
            "anyOf": [
              {
                "enum": [
                  "deep_search",
                  "qa",
                  "workbook"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Which console history this deep-search job belongs to. `deep_search` is the public route and the Deep Search page; `qa` and `workbook` are the console chat skins over the same agent. It does not pick the implementation. Null for fact-search and every non-deep-search kind. Jobs stored before this field existed echo `deep_search`. Read from the stored payload, so it rides the same retention path as `query`.",
            "title": "Surface"
          },
          "units": {
            "default": 0,
            "description": "Measured work in legacy credit units, retained even when a failed or cancelled job is not billed. Kept for compatibility: `credits` is the authoritative billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "What `credits` were charged for: one line per part (the parse, the tool's own work), with the quantity, rate and multiplier behind each. Null until `usage_final` is true, and on jobs finalized before usage breakdowns were introduced."
          },
          "usage_final": {
            "default": false,
            "description": "True once `credits` is final and will not change. False while the job is queued or running, and until any cleanup of its delegated stages has been accounted for. A failed tool job (read_file, run_sql, hybrid_search, grep, file_metadata, folder_metadata) created with an Idempotency-Key stays false for one hour after it fails, because a retry with the same key re-runs it; after that hour it is final and the retry returns the stored error.",
            "title": "Usage Final",
            "type": "boolean"
          },
          "usage_finalized_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "When `credits` became final. Null until `usage_final` is true.",
            "title": "Usage Finalized At"
          },
          "workspace_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The workspace this job reads. Null for a document operation whose source is an upload, a URL, or a prior parse result.",
            "title": "Workspace Id"
          }
        },
        "required": [
          "job_id",
          "status",
          "created_at"
        ],
        "title": "WorkspaceDeleteJob",
        "type": "object"
      },
      "WorkspaceDeleteResult": {
        "additionalProperties": false,
        "description": "Hard tenant deletion: storage prefix, indexes, and graph.",
        "properties": {
          "files_deleted": {
            "default": 0,
            "title": "Files Deleted",
            "type": "integer"
          },
          "index_documents_deleted": {
            "default": 0,
            "title": "Index Documents Deleted",
            "type": "integer"
          },
          "kg_nodes_deleted": {
            "default": 0,
            "title": "Kg Nodes Deleted",
            "type": "integer"
          },
          "prefix_deleted": {
            "default": false,
            "title": "Prefix Deleted",
            "type": "boolean"
          },
          "result_type": {
            "const": "workspace_delete",
            "default": "workspace_delete",
            "title": "Result Type",
            "type": "string"
          },
          "verified": {
            "default": false,
            "title": "Verified",
            "type": "boolean"
          },
          "workspace_id": {
            "format": "uuid",
            "title": "Workspace Id",
            "type": "string"
          }
        },
        "required": [
          "workspace_id"
        ],
        "title": "WorkspaceDeleteResult",
        "type": "object"
      },
      "WorkspaceFileSource": {
        "additionalProperties": false,
        "description": "A file already in a workspace.\n\nThe single seam between the two contexts: a granular operation may read a\nworkspace file and still write nothing back. The file need **not** be\ningested — granular operations read source bytes, not representations.",
        "properties": {
          "file_id": {
            "description": "File id from GET /v1/workspaces/{workspace_id}/files.",
            "format": "uuid",
            "title": "File Id",
            "type": "string"
          },
          "type": {
            "const": "workspace_file",
            "default": "workspace_file",
            "title": "Type",
            "type": "string"
          },
          "workspace_id": {
            "description": "Workspace that owns the file.",
            "format": "uuid",
            "title": "Workspace Id",
            "type": "string"
          }
        },
        "required": [
          "workspace_id",
          "file_id"
        ],
        "title": "WorkspaceFileSource",
        "type": "object"
      },
      "WorkspacePurpose": {
        "description": "Why the platform provisioned a workspace nobody asked for.\n\nA purposed workspace is platform-managed: it is created on a person's\nbehalf and it refuses deletion, so a caller can tell from a list response\nwhich row will answer 409 rather than discovering it by trying.",
        "enum": [
          "perception_playground"
        ],
        "title": "WorkspacePurpose",
        "type": "string"
      },
      "WorkspaceQueryScope": {
        "additionalProperties": false,
        "description": "The question ran against the whole workspace.",
        "properties": {
          "type": {
            "const": "workspace",
            "default": "workspace",
            "title": "Type",
            "type": "string"
          }
        },
        "title": "WorkspaceQueryScope",
        "type": "object"
      },
      "WorkspaceShares": {
        "additionalProperties": false,
        "description": "The owner and explicit users who may access one workspace.",
        "properties": {
          "owner_user_id": {
            "anyOf": [
              {
                "format": "uuid",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Console user who owns the workspace, or null for an organization-owned integration workspace.",
            "title": "Owner User Id"
          },
          "user_ids": {
            "description": "Console users with explicit access to the workspace; excludes the owner.",
            "items": {
              "format": "uuid",
              "type": "string"
            },
            "title": "User Ids",
            "type": "array"
          },
          "workspace_id": {
            "description": "Workspace whose sharing configuration this response describes.",
            "format": "uuid",
            "title": "Workspace Id",
            "type": "string"
          }
        },
        "required": [
          "workspace_id",
          "owner_user_id",
          "user_ids"
        ],
        "title": "WorkspaceShares",
        "type": "object"
      },
      "WorkspaceStats": {
        "additionalProperties": false,
        "description": "Per-workspace content summary.\n\n``files_by_ingestion_status`` is the completeness instrument: a caller does\nnot need to page through ``list_files`` to know whether anything is stale.\n``stale > 0`` means observed and ingested hashes diverged — call\n``POST .../ingestions`` with ``stale_only=true`` to catch up.  ``expired >\n0`` means derived representations were dropped by retention; a re-ingest is\nneeded to make those files searchable again.",
        "properties": {
          "bytes_total": {
            "title": "Bytes Total",
            "type": "integer"
          },
          "files_by_ingestion_status": {
            "additionalProperties": {
              "type": "integer"
            },
            "propertyNames": {
              "$ref": "#/components/schemas/IngestionStatus"
            },
            "title": "Files By Ingestion Status",
            "type": "object"
          },
          "files_expiring_within_7d": {
            "title": "Files Expiring Within 7D",
            "type": "integer"
          },
          "files_total": {
            "title": "Files Total",
            "type": "integer"
          },
          "index_documents": {
            "title": "Index Documents",
            "type": "integer"
          },
          "kg_edges": {
            "description": "Edges in the workspace's published knowledge graph; 0 when none is built.",
            "title": "Kg Edges",
            "type": "integer"
          },
          "kg_nodes": {
            "description": "Nodes in the workspace's published knowledge graph; 0 when none is built.",
            "title": "Kg Nodes",
            "type": "integer"
          },
          "last_ingestion_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Ingestion At"
          },
          "last_reconciliation_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Reconciliation At"
          },
          "next_expiry_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Earliest artifact ``expires_at``; null when nothing expires.",
            "title": "Next Expiry At"
          },
          "pages_ingested": {
            "title": "Pages Ingested",
            "type": "integer"
          }
        },
        "required": [
          "files_total",
          "files_by_ingestion_status",
          "bytes_total",
          "pages_ingested",
          "index_documents",
          "kg_nodes",
          "kg_edges",
          "last_ingestion_at",
          "last_reconciliation_at",
          "next_expiry_at",
          "files_expiring_within_7d"
        ],
        "title": "WorkspaceStats",
        "type": "object"
      },
      "WorkspaceStatus": {
        "description": "Lifecycle states visible on the API surface.\n\n``deleted`` is a final internal state; a deleted workspace never appears in\nany list or ``get`` response — it is as if it never existed.",
        "enum": [
          "active",
          "deleting"
        ],
        "title": "WorkspaceStatus",
        "type": "string"
      },
      "ndi_service__app__platform_api__contracts__JobStatus": {
        "description": "``cancelled`` is a first-class terminal status, not a ``failed`` variant.\n\nConflating them makes error-rate metrics lie and forces every client to\nstring-match an error code.",
        "enum": [
          "queued",
          "running",
          "succeeded",
          "failed",
          "cancelled"
        ],
        "title": "JobStatus",
        "type": "string"
      },
      "ndi_service__app__platform_api__document_operations__schemas__ExtractSchemaValidationRequest": {
        "additionalProperties": false,
        "description": "Body for ``POST /v1/extract/schema-validation``.\n\nSame mutual-exclusion rule as :class:`ExtractRequest`: exactly one of\n``schema_id`` or ``schema`` must be present. Optional ``schema_version``\npins a registry version when resolving ``schema_id``.",
        "properties": {
          "schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Inline JSON Schema to validate. Mutually exclusive with schema_id.",
            "title": "Schema"
          },
          "schema_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catalog schema family id (sch_...). Mutually exclusive with an inline schema.",
            "title": "Schema Id"
          },
          "schema_version": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pin a published catalog version. Omit with schema_id to use the latest version.",
            "title": "Schema Version"
          }
        },
        "title": "ExtractSchemaValidationRequest",
        "type": "object"
      },
      "ndi_service__app__platform_api__document_operations__schemas__ExtractSchemaValidationResponse": {
        "additionalProperties": false,
        "description": "Result of ``POST /v1/extract/schema-validation``.\n\nOn a valid schema, ``valid=True`` and ``normalized_schema`` carries the\ncompiled form.  On an invalid schema, ``valid=False`` and ``errors``\nlists every violation found — the whole list, not just the first.",
        "properties": {
          "errors": {
            "description": "Every validation violation found. Empty when valid is true.",
            "items": {
              "$ref": "#/components/schemas/SchemaError"
            },
            "title": "Errors",
            "type": "array"
          },
          "normalized_schema": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compiled schema when valid is true. Null when the input was rejected.",
            "title": "Normalized Schema"
          },
          "valid": {
            "description": "True when the schema can be used as an extract schema.",
            "title": "Valid",
            "type": "boolean"
          }
        },
        "required": [
          "valid"
        ],
        "title": "ExtractSchemaValidationResponse",
        "type": "object"
      },
      "ndi_service__app__platform_api__document_operations__schemas__GroundOptions": {
        "additionalProperties": false,
        "properties": {
          "include_previews": {
            "default": false,
            "description": "When true, matches include cropped_image_url for visual regions. Fetch with the same API key.",
            "title": "Include Previews",
            "type": "boolean"
          },
          "max_matches": {
            "default": 10,
            "description": "Maximum matches to return per target, ranked best-first. An HTML source is capped the same way, but only visible rendered text is matched: text hidden by its own style attribute, a hidden or aria-hidden attribute, or an unopened <dialog> is never returned. Hiding that comes from a stylesheet or a media query is not evaluated. A hint ranks the visible occurrence nearest that nearby text first; without a hint, rank 1 is the first visible occurrence.",
            "maximum": 50.0,
            "minimum": 1.0,
            "title": "Max Matches",
            "type": "integer"
          },
          "minimum_semantic_score": {
            "anyOf": [
              {
                "maximum": 1.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Deprecated minimum score for semantic and model-scored matches. The exact-match PDF, Word and PowerPoint runtime ignores it: a semantic pick there is kept only when the model rates it above no answer. Exact and normalized matches are unaffected.",
            "title": "Minimum Semantic Score"
          },
          "require_visual_region": {
            "default": false,
            "description": "When true, only matches that have a visual region are kept. Not supported by the current runtime.",
            "title": "Require Visual Region",
            "type": "boolean"
          },
          "use_word_level_grounding": {
            "default": false,
            "description": "Experimental. Match targets against word-level OCR bboxes. PDF sources only. Targets shorter than 2 normalized characters return status failed with error needle_too_short.",
            "title": "Use Word Level Grounding",
            "type": "boolean"
          }
        },
        "title": "GroundOptions",
        "type": "object"
      },
      "ndi_service__app__platform_api__document_operations__schemas__UploadResponse": {
        "additionalProperties": false,
        "description": "Returned by ``POST /v1/uploads`` on success.\n\n``upload_id`` is the handle passed to :class:`~ndi_service.app.platform_api.contracts.UploadSource`.\nOrdinary bytes stay until explicit deletion; Zero retention remains separate.",
        "properties": {
          "content_hash": {
            "description": "SHA-256 hex digest of the staged bytes. Confirms the upload is the file you sent, not a workspace file id.",
            "title": "Content Hash",
            "type": "string"
          },
          "expires_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Zero retention cleanup deadline; null for ordinary uploads kept until explicit deletion.",
            "title": "Expires At"
          },
          "file_name": {
            "description": "Original filename as received.",
            "title": "File Name",
            "type": "string"
          },
          "size_bytes": {
            "description": "Byte length of the staged file, after upload completes.",
            "title": "Size Bytes",
            "type": "integer"
          },
          "upload_id": {
            "description": "Handle to pass as source.upload_id on a later document operation.",
            "format": "uuid",
            "title": "Upload Id",
            "type": "string"
          }
        },
        "required": [
          "upload_id",
          "file_name",
          "size_bytes",
          "content_hash",
          "expires_at"
        ],
        "title": "UploadResponse",
        "type": "object"
      },
      "ndi_service__app__platform_api__domains__schemas__Taxonomy": {
        "additionalProperties": false,
        "description": "The classification vocabulary.",
        "properties": {
          "allow_other": {
            "const": true,
            "default": true,
            "description": "Cannot be disabled: a document that fits nothing is labelled 'other', never force-fitted.",
            "title": "Allow Other",
            "type": "boolean"
          },
          "classes": {
            "items": {
              "$ref": "#/components/schemas/TaxonomyClass"
            },
            "maxItems": 400,
            "title": "Classes",
            "type": "array"
          }
        },
        "title": "Taxonomy",
        "type": "object"
      },
      "ndi_service__app__platform_api__operations__schemas__UsageResponse": {
        "additionalProperties": false,
        "description": "Usage report covering ``[period_start, period_end]``.\n\n``units_total`` sums measured work, including free failed and cancelled jobs.\n``credits_total`` sums final billable credits for the period.",
        "properties": {
          "buckets": {
            "items": {
              "$ref": "#/components/schemas/UsageBucket"
            },
            "title": "Buckets",
            "type": "array"
          },
          "credits_total": {
            "description": "Sum of `credits` across all buckets: final credits for the period.",
            "title": "Credits Total",
            "type": "integer"
          },
          "group_by": {
            "title": "Group By",
            "type": "string"
          },
          "period_end": {
            "format": "date",
            "title": "Period End",
            "type": "string"
          },
          "period_start": {
            "format": "date",
            "title": "Period Start",
            "type": "string"
          },
          "units_total": {
            "title": "Units Total",
            "type": "integer"
          }
        },
        "required": [
          "period_start",
          "period_end",
          "group_by",
          "buckets",
          "units_total",
          "credits_total"
        ],
        "title": "UsageResponse",
        "type": "object"
      },
      "ndi_service__app__platform_api__results__CategorizeResult": {
        "additionalProperties": false,
        "properties": {
          "assignments": {
            "items": {
              "$ref": "#/components/schemas/CategoryAssignment"
            },
            "title": "Assignments",
            "type": "array"
          },
          "result_type": {
            "const": "categorize",
            "default": "categorize",
            "title": "Result Type",
            "type": "string"
          },
          "units": {
            "title": "Units",
            "type": "integer"
          },
          "warnings": {
            "description": "Parse settings this run accepted but did not apply, each naming the setting and why, for example a page selection on a file with no pages. Left out when empty.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "assignments",
          "units"
        ],
        "title": "CategorizeResult",
        "type": "object"
      },
      "ndi_service__app__platform_api__results__ExtractResult": {
        "additionalProperties": false,
        "properties": {
          "converted_pdf_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authenticated PDF preview used to measure citation regions for an office source.",
            "title": "Converted Pdf Url"
          },
          "data": {
            "additionalProperties": true,
            "description": "Object shaped by the request schema. Missing values are null, not omitted.",
            "title": "Data",
            "type": "object"
          },
          "disclosures": {
            "description": "Structured signals about how this result was produced. Empty when all behaviours matched what the caller would assume without them.",
            "items": {
              "discriminator": {
                "mapping": {
                  "classification_gap_fill": "#/components/schemas/ClassificationGapFillDisclosure",
                  "classification_unread_pages": "#/components/schemas/ClassificationUnreadPagesDisclosure",
                  "content_truncated": "#/components/schemas/ContentTruncatedDisclosure",
                  "extraction_null_on_success": "#/components/schemas/ExtractionNullOnSuccessDisclosure",
                  "parse_fidelity": "#/components/schemas/ParseFidelityDisclosure",
                  "parse_vendor_provenance": "#/components/schemas/ParseVendorProvenanceDisclosure",
                  "source_incomplete": "#/components/schemas/SourceIncompleteDisclosure"
                },
                "propertyName": "code"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ClassificationGapFillDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ClassificationUnreadPagesDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ExtractionNullOnSuccessDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ParseVendorProvenanceDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ParseFidelityDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ContentTruncatedDisclosure"
                },
                {
                  "$ref": "#/components/schemas/SourceIncompleteDisclosure"
                }
              ]
            },
            "title": "Disclosures",
            "type": "array"
          },
          "enrichment_status": {
            "default": "complete",
            "description": "Pending means values are available while citations and other enrichment are still running. Complete means enrichment finished; degraded means it finished with a reported enrichment failure. Always read the job status for cancellation or failure.",
            "enum": [
              "pending",
              "complete",
              "degraded"
            ],
            "title": "Enrichment Status",
            "type": "string"
          },
          "fields": {
            "description": "One entry per schema field, including not_found. A missing value is never silently dropped.",
            "items": {
              "$ref": "#/components/schemas/ExtractedField"
            },
            "title": "Fields",
            "type": "array"
          },
          "result_type": {
            "const": "extract",
            "default": "extract",
            "title": "Result Type",
            "type": "string"
          },
          "schema_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catalog schema family id when a registry schema was used.",
            "title": "Schema Id"
          },
          "schema_version": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catalog version that was frozen at accept time.",
            "title": "Schema Version"
          },
          "units": {
            "description": "Measured work units for this extraction. The job's `credits` is the final billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "unrefined_field_paths": {
            "description": "JSON paths of found fields whose citation does not point at the exact line the value was read from: it is a broader document region, or absent. The values are correct. The exact location could not be measured, for example because the quote's words are laid out differently on the page than in the text, or the value is printed identically in several places and nothing said which one. A value is never boxed at its first occurrence instead. Empty when citations are off.",
            "items": {
              "type": "string"
            },
            "title": "Unrefined Field Paths",
            "type": "array"
          },
          "warnings": {
            "description": "Non-fatal notes about the request, e.g. instructions no schema field can satisfy.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "fields",
          "units"
        ],
        "title": "ExtractResult",
        "type": "object"
      },
      "ndi_service__app__platform_api__results__GroundResult": {
        "additionalProperties": false,
        "properties": {
          "converted_pdf_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "PDF the office source was converted to before grounding. Match regions are measured on this PDF. Null when the source was already a PDF or did not need conversion.",
            "title": "Converted Pdf Url"
          },
          "result_type": {
            "const": "ground",
            "default": "ground",
            "title": "Result Type",
            "type": "string"
          },
          "targets": {
            "description": "One result per request target, in request order.",
            "items": {
              "$ref": "#/components/schemas/GroundTargetResult"
            },
            "title": "Targets",
            "type": "array"
          },
          "transcript_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Storage URL of the MediaTimeline JSON used for grounding.",
            "title": "Transcript Url"
          },
          "units": {
            "description": "Measured work units for this ground job. The job's `credits` is the final billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "warnings": {
            "description": "Parse settings this run accepted but did not apply, each naming the setting and why, for example a page selection on a file with no pages. Left out when empty.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "targets",
          "units"
        ],
        "title": "GroundResult",
        "type": "object"
      },
      "ndi_service__app__platform_api__results__ParseResult": {
        "additionalProperties": false,
        "properties": {
          "converted_pdf_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "PDF the office source was converted to before parsing. Block geometry is measured on this PDF. Null when the source was already a PDF or did not need conversion.",
            "title": "Converted Pdf Url"
          },
          "disclosures": {
            "description": "Structured signals about how this result was produced. Empty when all behaviours matched what the caller would assume without them.",
            "items": {
              "discriminator": {
                "mapping": {
                  "classification_gap_fill": "#/components/schemas/ClassificationGapFillDisclosure",
                  "classification_unread_pages": "#/components/schemas/ClassificationUnreadPagesDisclosure",
                  "content_truncated": "#/components/schemas/ContentTruncatedDisclosure",
                  "extraction_null_on_success": "#/components/schemas/ExtractionNullOnSuccessDisclosure",
                  "parse_fidelity": "#/components/schemas/ParseFidelityDisclosure",
                  "parse_vendor_provenance": "#/components/schemas/ParseVendorProvenanceDisclosure",
                  "source_incomplete": "#/components/schemas/SourceIncompleteDisclosure"
                },
                "propertyName": "code"
              },
              "oneOf": [
                {
                  "$ref": "#/components/schemas/ClassificationGapFillDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ClassificationUnreadPagesDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ExtractionNullOnSuccessDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ParseVendorProvenanceDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ParseFidelityDisclosure"
                },
                {
                  "$ref": "#/components/schemas/ContentTruncatedDisclosure"
                },
                {
                  "$ref": "#/components/schemas/SourceIncompleteDisclosure"
                }
              ]
            },
            "title": "Disclosures",
            "type": "array"
          },
          "document": {
            "$ref": "#/components/schemas/ParseDocument",
            "description": "Parsed text, blocks, chunks, and optional spreadsheet sidecars."
          },
          "file_name": {
            "description": "Source filename recorded for this run.",
            "title": "File Name",
            "type": "string"
          },
          "lane": {
            "description": "Which parser lane produced this payload, for example document or spreadsheet.",
            "title": "Lane",
            "type": "string"
          },
          "ocr_applied": {
            "description": "True when OCR actually ran, regardless of the requested ocr.mode.",
            "title": "Ocr Applied",
            "type": "boolean"
          },
          "result_type": {
            "const": "parse",
            "default": "parse",
            "title": "Result Type",
            "type": "string"
          },
          "transcript": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MediaTimeline"
              },
              {
                "type": "null"
              }
            ],
            "description": "Inline MediaTimeline for audio/video so the console JSON tab can show segments. Null for non-media, historical jobs, and list responses."
          },
          "transcript_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Authenticated job-scoped MediaTimeline JSON for audio/video. Null for non-media and historical jobs.",
            "title": "Transcript Url"
          },
          "units": {
            "description": "Measured work units for this parse, typically one per page. The job's `credits` is the final billed amount.",
            "title": "Units",
            "type": "integer"
          },
          "warnings": {
            "description": "Parse settings this run accepted but did not apply, each naming the setting and why, for example a page selection on a file with no pages. Left out when empty.",
            "items": {
              "type": "string"
            },
            "title": "Warnings",
            "type": "array"
          }
        },
        "required": [
          "file_name",
          "lane",
          "document",
          "ocr_applied",
          "units"
        ],
        "title": "ParseResult",
        "type": "object"
      }
    },
    "securitySchemes": {
      "APIKeyHeader": {
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      },
      "HTTPBearer": {
        "description": "OIDC access token from the console sign-in.",
        "scheme": "bearer",
        "type": "http"
      },
      "UploadGrantHeader": {
        "description": "Short-lived upload grant from POST /v1/workspaces/{workspace_id}/upload-grants.",
        "in": "header",
        "name": "X-Upload-Token",
        "type": "apiKey"
      },
      "UploadSessionTokenHeader": {
        "description": "Session token from POST /v1/workspaces/{workspace_id}/upload-sessions.",
        "in": "header",
        "name": "X-Upload-Token",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "description": "Document intelligence: parse, split, classify, extract, and ground files, or build a searchable workspace. Authenticate with ``X-API-Key``.",
    "title": "NDI Platform API",
    "version": "0.1.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/access-labels": {
      "get": {
        "description": "List the caller's reusable access labels. Cost class: cacheable.",
        "operationId": "list_access_labels_v1_access_labels_get",
        "parameters": [
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_AccessLabelCatalogEntry_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_access_labels",
        "tags": [
          "access-labels"
        ]
      },
      "post": {
        "description": "Add a label to the tenant catalog.",
        "operationId": "create_access_label_v1_access_labels_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccessLabelRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessLabelCatalogEntry"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_access_label",
        "tags": [
          "access-labels"
        ]
      }
    },
    "/v1/access-labels/{access_label_id}": {
      "delete": {
        "description": "Delete a catalog label. Refused with 409 when any workspace, grant, or file still uses the name.",
        "operationId": "delete_access_label_v1_access_labels__access_label_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "access_label_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Access Label Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "delete_access_label",
        "tags": [
          "access-labels"
        ]
      },
      "get": {
        "description": "Fetch one catalog label.",
        "operationId": "get_access_label_v1_access_labels__access_label_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "access_label_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Access Label Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessLabelCatalogEntry"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_access_label",
        "tags": [
          "access-labels"
        ]
      },
      "patch": {
        "description": "Update a catalog label's description.",
        "operationId": "update_access_label_v1_access_labels__access_label_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "access_label_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Access Label Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateAccessLabelRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessLabelCatalogEntry"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "update_access_label",
        "tags": [
          "access-labels"
        ]
      }
    },
    "/v1/classify": {
      "post": {
        "description": "Classify one document against caller-provided classes.\n\nCost class: **job** (model inference per document; billed on completion).\n\nThe canonical p0 input is one document, matching the routing use case and\ncommon industry shape.\n\nReturns ``202`` immediately unless ``?wait_seconds=N`` is set; the result\ncarries ranked label units for the requested document or page granularity.",
        "operationId": "classify_v1_classify_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClassifyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/ClassifyJob"
                    },
                    {
                      "$ref": "#/components/schemas/CategorizeJob"
                    }
                  ],
                  "title": "Response Classify V1 Classify Post"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "classify",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/cli/device/code": {
      "post": {
        "operationId": "issue_device_code_v1_cli_device_code_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Payment Required"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Request Entity Too Large"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Service Unavailable"
          }
        },
        "summary": "issue_device_code",
        "tags": [
          "cli"
        ]
      }
    },
    "/v1/cli/device/token": {
      "post": {
        "operationId": "poll_device_token_v1_cli_device_token_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeviceTokenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Bad Request"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Payment Required"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "413": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Request Entity Too Large"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Service Unavailable"
          }
        },
        "summary": "poll_device_token",
        "tags": [
          "cli"
        ]
      }
    },
    "/v1/domains": {
      "get": {
        "description": "List every domain visible to the caller. Cost class: cacheable.\n\nReturns the platform-owned domains (``generic`` and the curated verticals,\nall published and selectable) and the calling tenant's own rows.",
        "operationId": "list_domains_v1_domains_get",
        "parameters": [
          {
            "description": "Filter by ownership: `platform` (standard) or `tenant` (yours).",
            "in": "query",
            "name": "owner",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "platform",
                    "tenant"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by ownership: `platform` (standard) or `tenant` (yours).",
              "title": "Owner"
            }
          },
          {
            "description": "Filter by lifecycle status.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "draft",
                    "published"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by lifecycle status.",
              "title": "Status"
            }
          },
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_DomainSummary_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_domains",
        "tags": [
          "domains"
        ]
      },
      "post": {
        "description": "Create a tenant-owned draft. Cost class: fast.\n\nThe draft is editable and **unusable** until published. Validation runs on\nevery write and is returned every time, so a caller never has to guess\nwhether a publish will succeed.",
        "operationId": "create_domain_v1_domains_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDomainRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_domain",
        "tags": [
          "domains"
        ]
      }
    },
    "/v1/domains/generate": {
      "post": {
        "description": "Draft a taxonomy from a description or Parse job. Cost class: slow.\n\nSynchronous and **non-persisting**: the model proposes a taxonomy the author\nedits, then posts to ``POST /v1/domains``. Nothing is written to the\ndatabase and no job is created. Kept off MCP because authoring is a reviewed\nhuman act, not an agent-loop step.",
        "operationId": "generate_domain_v1_domains_generate_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateDomainRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerateDomainResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "generate_domain",
        "tags": [
          "domains"
        ]
      }
    },
    "/v1/domains/suggest-description": {
      "post": {
        "description": "Draft a classifier-facing description from a domain name. Cost class: slow.\n\nSynchronous and **non-persisting**. The console uses this to prefill the\nGenerate tab. An unrecognized name returns an empty description rather than\nan error so the author can type their own. Kept off MCP because authoring\nis a reviewed human act, not an agent-loop step.",
        "operationId": "suggest_domain_description_v1_domains_suggest_description_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SuggestDomainDescriptionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuggestDomainDescriptionResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "suggest_domain_description",
        "tags": [
          "domains"
        ]
      }
    },
    "/v1/domains/{domain_id}": {
      "get": {
        "description": "Read one domain version, with inheritance already resolved. Cost class: cacheable.\n\nA caller reading a domain wants the vocabulary that will actually be applied,\nnot a delta they have to merge themselves.",
        "operationId": "get_domain_v1_domains__domain_id__get",
        "parameters": [
          {
            "description": "Domain version identifier.",
            "in": "path",
            "name": "domain_id",
            "required": true,
            "schema": {
              "description": "Domain version identifier.",
              "format": "uuid",
              "title": "Domain Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_domain",
        "tags": [
          "domains"
        ]
      },
      "patch": {
        "description": "Edit a draft, or spin a published version into the next draft. Cost class: fast.\n\nEditing a ``draft`` mutates it. Editing a ``published`` domain creates version\n*n+1* and leaves version *n* untouched. Existing workspaces remain pinned to\nthe version selected at creation; the new version is available only to future\nworkspaces.",
        "operationId": "update_domain_v1_domains__domain_id__patch",
        "parameters": [
          {
            "description": "Domain version identifier.",
            "in": "path",
            "name": "domain_id",
            "required": true,
            "schema": {
              "description": "Domain version identifier.",
              "format": "uuid",
              "title": "Domain Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDomainRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "update_domain",
        "tags": [
          "domains"
        ]
      }
    },
    "/v1/domains/{domain_id}/publish": {
      "post": {
        "description": "Freeze a draft version and make it selectable by workspaces. Cost class: fast.\n\nThe gate rejects empty or oversized taxonomies, duplicate\n``group/subgroup`` paths, and attempts to redefine ``other``.\n\nThere is no delete route — a workspace whose domain vanished could not\nexplain its own categories. Move workspaces to a newer version instead.",
        "operationId": "publish_domain_v1_domains__domain_id__publish_post",
        "parameters": [
          {
            "description": "Domain version identifier.",
            "in": "path",
            "name": "domain_id",
            "required": true,
            "schema": {
              "description": "Domain version identifier.",
              "format": "uuid",
              "title": "Domain Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "publish_domain",
        "tags": [
          "domains"
        ]
      }
    },
    "/v1/extract": {
      "post": {
        "description": "Extract schema-shaped structured data from a document.\n\nCost class: **job** (LLM inference + parsing; billed on completion).\n\nProvide an inline ``schema`` or a registered ``schema_id``. The effective\nschema is validated before the job is accepted; use\n``POST /v1/extract/schema-validation`` to pre-check yours. Exactly one of\n``schema_id`` or ``schema`` must be present. Optional ``schema_version``\npins a registry version when ``schema_id`` is set.\n\nCitations are enabled by default (``citations.enabled=true``). Located\nfields carry :class:`~ndi_service.app.platform_api.contracts.Citation`\nentries (``location`` + optional ``source_text``). A field the model could\nnot find is returned as ``status=not_found``, never silently omitted.",
        "operationId": "extract_v1_extract_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExtractRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "extract",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/extract/schema-validation": {
      "post": {
        "description": "Validate an extraction schema without creating a job or consuming credits.\n\nCost class: **fast** (pure validation, no I/O, no model inference).\n\nUse this before submitting an ``extract`` job to catch schema errors up\nfront.  On success ``valid=True`` and ``normalized_schema`` carries the\ncompiled form the extraction pipeline will use.  On failure ``valid=False``\nand ``errors`` lists every violation — the whole list, not just the first.",
        "operationId": "validate_extract_schema_v1_extract_schema_validation_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ndi_service__app__platform_api__document_operations__schemas__ExtractSchemaValidationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ndi_service__app__platform_api__document_operations__schemas__ExtractSchemaValidationResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "validate_extract_schema",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/extraction-schemas": {
      "get": {
        "description": "List the latest version of every schema family visible to the caller.\n\nCost class: cacheable. Tenant schemas and platform schemas are both listed;\nwhen both share a ``schema_id``, the tenant row wins.",
        "operationId": "list_extraction_schemas_v1_extraction_schemas_get",
        "parameters": [
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_ExtractionSchemaSummary_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_extraction_schemas",
        "tags": [
          "extraction-schemas"
        ]
      },
      "post": {
        "description": "Create version 1 of a new tenant-owned schema family with a generated ``sch_...`` id.",
        "operationId": "create_extraction_schema_v1_extraction_schemas_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExtractionSchemaRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractionSchema"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_extraction_schema",
        "tags": [
          "extraction-schemas"
        ]
      }
    },
    "/v1/extraction-schemas/{schema_id}": {
      "delete": {
        "description": "Delete a schema family you created, with every version. Cost class: fast.\n\nThe family stops listing and resolving at once: ``GET`` answers 404, and an\nExtract naming it fails ``schema_not_found``. Jobs accepted before the delete\nkeep the copy of the schema they took at accept time and finish normally;\ntheir results still name the ``schema_id`` and ``schema_version`` they used.\nDeleting a family that is already deleted succeeds again. Platform schemas,\nand another tenant's or another external account's, answer 404.",
        "operationId": "delete_extraction_schema_v1_extraction_schemas__schema_id__delete",
        "parameters": [
          {
            "description": "Stable schema family id (``sch_...``).",
            "in": "path",
            "name": "schema_id",
            "required": true,
            "schema": {
              "description": "Stable schema family id (``sch_...``).",
              "title": "Schema Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "delete_extraction_schema",
        "tags": [
          "extraction-schemas"
        ]
      },
      "get": {
        "description": "Return the latest visible version of a schema family.",
        "operationId": "get_extraction_schema_v1_extraction_schemas__schema_id__get",
        "parameters": [
          {
            "description": "Stable schema family id (``sch_...``).",
            "in": "path",
            "name": "schema_id",
            "required": true,
            "schema": {
              "description": "Stable schema family id (``sch_...``).",
              "title": "Schema Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractionSchema"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_extraction_schema",
        "tags": [
          "extraction-schemas"
        ]
      }
    },
    "/v1/extraction-schemas/{schema_id}/versions": {
      "get": {
        "description": "Page the immutable version history of one visible schema family.",
        "operationId": "list_extraction_schema_versions_v1_extraction_schemas__schema_id__versions_get",
        "parameters": [
          {
            "description": "Stable schema family id (``sch_...``).",
            "in": "path",
            "name": "schema_id",
            "required": true,
            "schema": {
              "description": "Stable schema family id (``sch_...``).",
              "title": "Schema Id",
              "type": "string"
            }
          },
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_ExtractionSchema_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_extraction_schema_versions",
        "tags": [
          "extraction-schemas"
        ]
      },
      "post": {
        "description": "Validate and append the next immutable integer version of a tenant-owned family.",
        "operationId": "create_extraction_schema_version_v1_extraction_schemas__schema_id__versions_post",
        "parameters": [
          {
            "description": "Stable schema family id (``sch_...``).",
            "in": "path",
            "name": "schema_id",
            "required": true,
            "schema": {
              "description": "Stable schema family id (``sch_...``).",
              "title": "Schema Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateExtractionSchemaVersionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractionSchema"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_extraction_schema_version",
        "tags": [
          "extraction-schemas"
        ]
      }
    },
    "/v1/extraction-schemas/{schema_id}/versions/{version}": {
      "get": {
        "description": "Return one immutable version of a visible schema family.",
        "operationId": "get_extraction_schema_version_v1_extraction_schemas__schema_id__versions__version__get",
        "parameters": [
          {
            "description": "Stable schema family id (``sch_...``).",
            "in": "path",
            "name": "schema_id",
            "required": true,
            "schema": {
              "description": "Stable schema family id (``sch_...``).",
              "title": "Schema Id",
              "type": "string"
            }
          },
          {
            "description": "Immutable integer version within the family.",
            "in": "path",
            "name": "version",
            "required": true,
            "schema": {
              "description": "Immutable integer version within the family.",
              "minimum": 1,
              "title": "Version",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractionSchema"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_extraction_schema_version",
        "tags": [
          "extraction-schemas"
        ]
      }
    },
    "/v1/ground": {
      "post": {
        "description": "Locate caller-provided target text in a document.\n\nCost class: **job** (retrieval + model inference per target; billed on\ncompletion).\n\nEach target is located independently and returns an honest location status:\n``found``, ``not_found``, or ``failed``.  Ground does not verify claims and\ndoes not produce contradiction verdicts.\n\nUp to MAX_CLAIM_BATCH targets or legacy claims per call; all are grounded\nagainst the same ``source``.",
        "operationId": "ground_v1_ground_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroundRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroundJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "ground",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/jobs": {
      "get": {
        "description": "List jobs for the authenticated tenant, newest first. Cost class: fast.\n\n``workspace_id`` narrows to workspace-scoped jobs; omitting it returns\ndocument-operation jobs too.  ``kind`` is the idiomatic way to list all\ningestion runs without a dedicated resource.\n\nPagination is keyset on ``(created_at, id)`` — OFFSET would silently miss\nor duplicate rows when new jobs arrive between pages.",
        "operationId": "list_jobs_v1_jobs_get",
        "parameters": [
          {
            "description": "Restrict to jobs that run in or read from this workspace. Omit to also include workspace-free document-operation jobs.",
            "in": "query",
            "name": "workspace_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to jobs that run in or read from this workspace. Omit to also include workspace-free document-operation jobs.",
              "title": "Workspace Id"
            }
          },
          {
            "description": "Filter by job kind. Filtering by kind makes a separate 'ingestion runs' resource unnecessary.",
            "in": "query",
            "name": "kind",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "items": {
                    "$ref": "#/components/schemas/JobKind"
                  },
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by job kind. Filtering by kind makes a separate 'ingestion runs' resource unnecessary.",
              "title": "Kind"
            }
          },
          {
            "description": "Filter by job status.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "items": {
                    "$ref": "#/components/schemas/JobStatus-Input"
                  },
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filter by job status.",
              "title": "Status"
            }
          },
          {
            "description": "Restrict to jobs created strictly after this timestamp (UTC).",
            "in": "query",
            "name": "created_after",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to jobs created strictly after this timestamp (UTC).",
              "title": "Created After"
            }
          },
          {
            "description": "Restrict to jobs sharing this caller-minted project id (the console's grouped runs).",
            "in": "query",
            "name": "project_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to jobs sharing this caller-minted project id (the console's grouped runs).",
              "title": "Project Id"
            }
          },
          {
            "deprecated": true,
            "description": "Lists return metadata only. During the console rollout, true is a deprecated compatibility mode limited to one result per page; read complete results with GET /jobs/{job_id}.",
            "in": "query",
            "name": "include_result",
            "required": false,
            "schema": {
              "default": false,
              "deprecated": true,
              "description": "Lists return metadata only. During the console rollout, true is a deprecated compatibility mode limited to one result per page; read complete results with GET /jobs/{job_id}.",
              "title": "Include Result",
              "type": "boolean"
            }
          },
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 20,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_Job_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_jobs",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}": {
      "delete": {
        "description": "Hide a job from listings and delete its content, keeping it for billing. Cost class: fast.\n\nThe row survives with its content-free billing fields, so ``units`` keep\nanswering and ``GET /v1/usage`` still counts the work; ``GET /v1/jobs`` stops\nreturning it. Reading it by id still works, with ``deleted_at`` set — the\nsame reasoning as an expired payload, where a 404 would conflate \"gone\" with\n\"never existed\".\n\nThe job's ``input``, ``result``, artifact files and source snapshot are\nremoved by the reaper's content-deletion leg on its next sweep (minutes), with\nthe same for an automatic search's delegated child: the delete only marks\nthe payload as expired now, so slow storage work stays out of the request.\nAfterwards the job reads as ``result_state=\"expired\"`` (a zero-retention job\nkeeps ``not_retained``). The same sweep deletes the perception-cache\nentries this job produced or consumed; one that another retained job of\nthe same tenant still reads stops serving hits and goes once that job's\ncontent is deleted.\n``input`` and ``result`` always go at that sweep. Only artifact files that\nanother retained job of the same tenant still uses (it reused this job's\nParse result, whose URLs point at them) are kept until that job's content\nis deleted; a later sweep deletes them. A job still queued or running that\nreuses this job's Parse result fails ``result_expired``. Bring-your-own-bucket\nfiles are never deleted.\n\nA job still queued or running is **cancelled first**, so hitting delete\nstops the compute rather than paying for a run nobody will ever see. A job\nthat finished under us is simply hidden: there was nothing left to stop, and\nrefusing the delete over a race the caller cannot see would be noise.\n\n``Temporal`` is not declared as a dependency here because asking for the\nclient connects: most deletes are of finished runs and need it for nothing,\nso an outage must not fail work that is entirely in Postgres.\n\nThere is no project-level route to pair with ``?project_id=``: a run's\nfan-out is one job per file, and the console deletes the group the same way\nit renames it — per job, over the ids it already holds.",
        "operationId": "delete_job_v1_jobs__job_id__delete",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "delete_job",
        "tags": [
          "operations"
        ]
      },
      "get": {
        "description": "Read a single job. Cost class: fast.\n\nThe poll target for every ``202``, and the only way an MCP agent tracks\nprogress.  A late poll returns the job with a ``result_state``, never a\n404 — \"this expired\" and \"this never existed\" are a scheduling problem and\na bug respectively, and a 404 would make them identical.\n``result_expired`` (410) is deliberately NOT used here because the row still\nexists and still answers for billing.",
        "operationId": "get_job_v1_jobs__job_id__get",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_job",
        "tags": [
          "operations"
        ]
      },
      "patch": {
        "description": "Rename a job. Cost class: fast.\n\n``name`` is the only mutable caller-facing field — the console uses it to\nrename a run (\"project\") after submission. Terminal jobs rename too: a\nfinished run's display name is presentation, not state.",
        "operationId": "update_job_v1_jobs__job_id__patch",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateJobRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "update_job",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/activity": {
      "get": {
        "description": "Read bounded private agent activity. Requires the initiating key and unchanged workspace access.",
        "operationId": "get_job_activity_v1_jobs__job_id__activity_get",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivitySnapshot"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_job_activity",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/activity/events": {
      "get": {
        "description": "Stream thinking and tools. Trimmed cursors reset to a snapshot; the final snapshot carries authoritative job status.",
        "operationId": "stream_job_activity_v1_jobs__job_id__activity_events_get",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "Replay cursor from a previous activity event or snapshot.",
            "in": "header",
            "name": "last-event-id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Replay cursor from a previous activity event or snapshot.",
              "title": "Last-Event-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "stream_job_activity",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/cancel": {
      "post": {
        "description": "Cancel a queued or running job. Cost class: fast.\n\nReturns the job in ``cancelled`` status.  ``cancelled`` is a first-class\nterminal status, not a ``failed`` variant — conflating them makes\nerror-rate metrics lie and forces every client to string-match an error\ncode.",
        "operationId": "cancel_job_v1_jobs__job_id__cancel_post",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/CancelJobRequest"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "cancel_job",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/content-download": {
      "post": {
        "description": "Start or poll Markdown generation; return a download grant when ready.",
        "operationId": "get_content_download_v1_jobs__job_id__content_download_post",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "Sheet name; omit for document content.",
            "in": "query",
            "name": "sheet_name",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Sheet name; omit for document content.",
              "title": "Sheet Name"
            }
          },
          {
            "description": "Restart a failed Markdown export.",
            "in": "query",
            "name": "retry",
            "required": false,
            "schema": {
              "default": false,
              "description": "Restart a failed Markdown export.",
              "title": "Retry",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentDownload"
                }
              }
            },
            "description": "Successful Response"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentDownload"
                }
              }
            },
            "description": "Accepted"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_parse_content_download",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/converted-pdf/{artifact_ref}": {
      "get": {
        "description": "Stream the office-conversion PDF after reauthorizing it against the owning job.",
        "operationId": "get_converted_pdf_content_v1_jobs__job_id__converted_pdf__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_converted_pdf_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/document-content/{artifact_ref}": {
      "get": {
        "description": "Stream complete reduced-layout Markdown after job authorization.",
        "operationId": "get_document_content_v1_jobs__job_id__document_content__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentDownload"
                }
              }
            },
            "description": "Accepted"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentDownload"
                }
              }
            },
            "description": "Conflict"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_document_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/download-links": {
      "post": {
        "description": "Sign a short-lived link to one file a succeeded job's result names.\n\nThe file is authorized exactly as its stable ``/jobs/{job_id}/{resource}/{ref}``\nURL authorizes it (per tenant, and for a service key per external account); the link then\nfetches the bytes without API-key headers until ``expires_at``: from S3\nwhen presigned, or from the API's token download on the local backend.",
        "operationId": "create_download_link_v1_jobs__job_id__download_links_post",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JobDownloadLinkRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobDownloadLink"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_job_download_link",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/events": {
      "get": {
        "description": "Stream job progress as Server-Sent Events. Cost class: fast.\n\nEach frame is a :class:`~ndi_service.app.platform_api.results.JobEvent`\nserialised as ``data: <json>\\n\\n`` with a monotonic ``id: <sequence>``.\nFrames are emitted by polling the job row — the row is the event source,\nso a frame appears whenever ``status`` or ``progress`` changes and the\nstream closes once the job is terminal (or after the same ceiling as the\ninline wait, for a job nothing is advancing).\n\n**REST and CLI only.** MCP has no streaming shape; an MCP agent polls\n``get_job`` instead.\n\n``Last-Event-ID`` offsets the sequence numbering so a reconnecting client\nkeeps a monotonic ``id``; the current state is always re-emitted as the\nfirst frame, because there is no event log to replay from.",
        "operationId": "stream_job_events_v1_jobs__job_id__events_get",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Last-Event-ID",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Last-Event-Id"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "stream_job_events",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/ground-crops/{artifact_ref}": {
      "get": {
        "description": "Stream a Ground crop after reauthorizing it against the owning job.",
        "operationId": "get_ground_crop_content_v1_jobs__job_id__ground_crops__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_ground_crop_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/ground-transcript/{artifact_ref}": {
      "get": {
        "description": "Stream a Ground transcript after reauthorizing it against the owning job.",
        "operationId": "get_ground_transcript_content_v1_jobs__job_id__ground_transcript__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_ground_transcript_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/parse-images/{artifact_ref}": {
      "get": {
        "description": "Stream an embedded picture after checking job ownership and membership.",
        "operationId": "get_parse_image_content_v1_jobs__job_id__parse_images__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_parse_image_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/parse-progress": {
      "get": {
        "description": "Read bounded ready-unit metadata. Preview content is fetched individually.",
        "operationId": "get_parse_progress_v1_jobs__job_id__parse_progress_get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParsePreviewSnapshot"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_parse_progress",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/parse-progress/events": {
      "get": {
        "description": "Stream current snapshots. Replaying one replaces units by immutable revision.",
        "operationId": "stream_parse_progress_v1_jobs__job_id__parse_progress_events_get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "stream_parse_progress",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/parse-progress/parts/{generation}/{revision}": {
      "get": {
        "description": "Read one checked preview after rechecking live source and destination access.",
        "operationId": "get_parse_progress_unit_v1_jobs__job_id__parse_progress_parts__generation___revision__get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "generation",
            "required": true,
            "schema": {
              "title": "Generation",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "revision",
            "required": true,
            "schema": {
              "title": "Revision",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParsePreviewContent"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_parse_progress_unit",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/parse-transcript/{artifact_ref}": {
      "get": {
        "description": "Stream a Parse transcript after reauthorizing it against the owning job.",
        "operationId": "get_parse_transcript_content_v1_jobs__job_id__parse_transcript__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_parse_transcript_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/request": {
      "get": {
        "description": "Read back the request a document operation ran under. Cost class: fast.\n\nWhat a finished run was *asked* for — the page selection, the schema, the\ntargets — so a caller can show the settings that produced a result, rebuild\nthe call that made it, or submit it again. ``Job.source`` names the document;\nthis names everything else.\n\nIts own route rather than a field on ``Job``: an extract schema or a ground\ntarget list is large, and ``GET /v1/jobs`` returns up to 200 rows.\n\nRetention is the same as the result's — the request is read from the stored\npayload, so it dies with it rather than outliving it.",
        "operationId": "get_job_request_v1_jobs__job_id__request_get",
        "parameters": [
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "discriminator": {
                    "mapping": {
                      "categorize": "#/components/schemas/CategorizeRequestEcho",
                      "classify": "#/components/schemas/ClassifyRequestEcho",
                      "extract": "#/components/schemas/ExtractRequestEcho",
                      "ground": "#/components/schemas/GroundRequestEcho",
                      "parse": "#/components/schemas/ParseRequestEcho",
                      "split": "#/components/schemas/SplitRequestEcho"
                    },
                    "propertyName": "request_type"
                  },
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ParseRequestEcho"
                    },
                    {
                      "$ref": "#/components/schemas/SplitRequestEcho"
                    },
                    {
                      "$ref": "#/components/schemas/ClassifyRequestEcho"
                    },
                    {
                      "$ref": "#/components/schemas/CategorizeRequestEcho"
                    },
                    {
                      "$ref": "#/components/schemas/ExtractRequestEcho"
                    },
                    {
                      "$ref": "#/components/schemas/GroundRequestEcho"
                    }
                  ],
                  "title": "Response Get Job Request V1 Jobs  Job Id  Request Get"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_job_request",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/split-artifacts/{artifact_ref}": {
      "get": {
        "description": "Stream a materialized Split segment after checking access to its owning job.",
        "operationId": "get_split_artifact_content_v1_jobs__job_id__split_artifacts__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_split_artifact_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/spreadsheet-cell-maps/{artifact_ref}": {
      "get": {
        "description": "Stream a Parse cell map after reauthorizing it against the owning job.",
        "operationId": "get_spreadsheet_cell_map_content_v1_jobs__job_id__spreadsheet_cell_maps__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_spreadsheet_cell_map_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/spreadsheet-content/{artifact_ref}": {
      "get": {
        "description": "Stream complete Markdown for an oversized sheet after job authorization.",
        "operationId": "get_spreadsheet_content_v1_jobs__job_id__spreadsheet_content__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentDownload"
                }
              }
            },
            "description": "Accepted"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContentDownload"
                }
              }
            },
            "description": "Conflict"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_spreadsheet_content",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/jobs/{job_id}/spreadsheet-rows/{artifact_ref}": {
      "get": {
        "description": "Read only the requested rows from the exact Parquet snapshot used by Parse.",
        "operationId": "get_parse_rows_v1_jobs__job_id__spreadsheet_rows__artifact_ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "artifact_ref",
            "required": true,
            "schema": {
              "title": "Artifact Ref",
              "type": "string"
            }
          },
          {
            "description": "Job identifier.",
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "description": "Job identifier.",
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          },
          {
            "description": "Zero-based first source row.",
            "in": "query",
            "name": "start_row",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Zero-based first source row.",
              "maximum": 9007199254740991,
              "minimum": 0,
              "title": "Start Row",
              "type": "integer"
            }
          },
          {
            "description": "Maximum rows to return.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Maximum rows to return.",
              "maximum": 100,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArtifactRowsPage"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_parse_rows",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/parse": {
      "post": {
        "description": "Parse a document into structured text, Markdown, or block JSON.\n\nCost class: **job** (processing units proportional to page count and OCR\nload; billed on completion).\n\nAccepts any source a granular operation can read — a staged upload, an\n``https://`` URL, a workspace file, or a prior Parse job.  Returns ``202`` with\na queued :class:`~ndi_service.app.platform_api.results.Job` immediately;\npass ``?wait_seconds=N`` to block up to N seconds for the result inline.\n\nOCR is applied automatically when the document needs it; the result's\n``ocr_applied`` flag reports whether it ran.",
        "operationId": "parse_v1_parse_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ParseRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParseJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "parse",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/playground/extract": {
      "post": {
        "description": "Extract structured fields under the anonymous playground try budget.",
        "operationId": "playground_extract_v1_playground_extract_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "cf-turnstile-response",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cf-Turnstile-Response"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_playground_extract_v1_playground_extract_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "summary": "playground_extract",
        "tags": [
          "playground"
        ]
      }
    },
    "/v1/playground/ground": {
      "post": {
        "description": "Locate caller-provided text under the anonymous playground try budget.",
        "operationId": "playground_ground_v1_playground_ground_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "cf-turnstile-response",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cf-Turnstile-Response"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_playground_ground_v1_playground_ground_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroundJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "summary": "playground_ground",
        "tags": [
          "playground"
        ]
      }
    },
    "/v1/playground/jobs/{job_id}": {
      "delete": {
        "description": "Cancel and erase the requesting anonymous visitor's job and its uploaded bytes.",
        "operationId": "playground_delete_job_v1_playground_jobs__job_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "summary": "playground_delete_job",
        "tags": [
          "playground"
        ]
      },
      "get": {
        "description": "Read a playground job owned by this anonymous visitor.",
        "operationId": "playground_get_job_v1_playground_jobs__job_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "job_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Job Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "summary": "playground_get_job",
        "tags": [
          "playground"
        ]
      }
    },
    "/v1/playground/parse": {
      "post": {
        "description": "Parse a document under the anonymous playground try budget.",
        "operationId": "playground_parse_v1_playground_parse_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "cf-turnstile-response",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cf-Turnstile-Response"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_playground_parse_v1_playground_parse_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParseJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "summary": "playground_parse",
        "tags": [
          "playground"
        ]
      }
    },
    "/v1/playground/quota": {
      "get": {
        "description": "Remaining free tries for this anonymous visitor. Does not consume a try.",
        "operationId": "playground_quota_v1_playground_quota_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaygroundQuota"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "summary": "playground_quota",
        "tags": [
          "playground"
        ]
      }
    },
    "/v1/playground/split": {
      "post": {
        "description": "Split a packet under the anonymous playground try budget.",
        "operationId": "playground_split_v1_playground_split_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "cf-turnstile-response",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Cf-Turnstile-Response"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_playground_split_v1_playground_split_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SplitJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "summary": "playground_split",
        "tags": [
          "playground"
        ]
      }
    },
    "/v1/split": {
      "post": {
        "description": "Split a document by page ranges or a spreadsheet by worksheet.\n\nSpreadsheet splitting is deterministic, does not classify tabs, and always\nreturns one materialized single-sheet XLSX artifact per segment.\n\nCost class: **job** (document parsing/inference when needed, or workbook\nnormalization and tab materialization; billed on completion).",
        "operationId": "split_v1_split_post",
        "parameters": [
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SplitRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SplitJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "split",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/systemone": {
      "post": {
        "description": "Answer typed questions about a state in one call, with probabilities.\n\nEach question is a yes/no (`noul`), a pick among named options (`choice`), or a\nposition on an ordered scale (`score`). Nothing is stored and no job is created.\nA deployment without a decision model answers `501 not_implemented`.",
        "operationId": "evaluate_systemone_v1_systemone_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SystemOneRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SystemOneResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "evaluate_systemone",
        "tags": [
          "systemone"
        ]
      }
    },
    "/v1/tenants": {
      "get": {
        "description": "List the partner's tenants, oldest first, disabled ones included. Cost class: cacheable.",
        "operationId": "list_tenants_v1_tenants_get",
        "parameters": [
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_Tenant_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_tenants",
        "tags": [
          "tenants"
        ]
      }
    },
    "/v1/tenants/{external_ref}": {
      "delete": {
        "description": "Disable the tenant and keep its data (default), or with ``purge=true`` delete all of it. Cost class: write.\n\nA disabled tenant is re-enabled with ``PUT`` and ``disabled: false``. A purge cannot be undone: the\ntenant is disabled at once, its jobs are cancelled, and every workspace, file, result, cache entry and\nkey is deleted. Only the content-free billing record (job ids, kinds, timestamps, units, credits) is\nkept. A purge already queued or running is returned as is; one that failed or ended unverified is\nstarted again. Once a purge has verified clean the ``external_ref`` no longer resolves, so a repeat of\nthis call answers ``tenant_not_found`` and a later ``PUT`` creates a new, empty tenant.",
        "operationId": "delete_tenant_v1_tenants__external_ref__delete",
        "parameters": [
          {
            "description": "The partner's own reference for the tenant, such as its account id.",
            "in": "path",
            "name": "external_ref",
            "required": true,
            "schema": {
              "description": "The partner's own reference for the tenant, such as its account id.",
              "maxLength": 128,
              "minLength": 1,
              "pattern": "^\\S(.*\\S)?$",
              "title": "External Ref",
              "type": "string"
            }
          },
          {
            "description": "True permanently deletes the tenant's data instead of disabling it. Answers 202 with a `tenant_purge` job to poll on GET /v1/jobs/{job_id} without X-NDI-Tenant.",
            "in": "query",
            "name": "purge",
            "required": false,
            "schema": {
              "default": false,
              "description": "True permanently deletes the tenant's data instead of disabling it. Answers 202 with a `tenant_purge` job to poll on GET /v1/jobs/{job_id} without X-NDI-Tenant.",
              "title": "Purge",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/Tenant"
                    },
                    {
                      "$ref": "#/components/schemas/TenantPurgeJob"
                    }
                  ],
                  "title": "Response Delete Tenant V1 Tenants  External Ref  Delete"
                }
              }
            },
            "description": "Successful Response"
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantPurgeJob"
                }
              }
            },
            "description": "The purge was accepted, or is already running."
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "delete_tenant",
        "tags": [
          "tenants"
        ]
      },
      "get": {
        "description": "Read one tenant. Cost class: cacheable.",
        "operationId": "get_tenant_v1_tenants__external_ref__get",
        "parameters": [
          {
            "description": "The partner's own reference for the tenant, such as its account id.",
            "in": "path",
            "name": "external_ref",
            "required": true,
            "schema": {
              "description": "The partner's own reference for the tenant, such as its account id.",
              "maxLength": 128,
              "minLength": 1,
              "pattern": "^\\S(.*\\S)?$",
              "title": "External Ref",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tenant"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_tenant",
        "tags": [
          "tenants"
        ]
      },
      "put": {
        "description": "Create the tenant, or update the one with this ``external_ref``.\n\nAnswers 201 when it was created and 200 when it already existed, so it is\nsafe to repeat. Limits above the partner's own are lowered to them.\nCost class: write.",
        "operationId": "put_tenant_v1_tenants__external_ref__put",
        "parameters": [
          {
            "description": "The partner's own reference for the tenant, such as its account id.",
            "in": "path",
            "name": "external_ref",
            "required": true,
            "schema": {
              "description": "The partner's own reference for the tenant, such as its account id.",
              "maxLength": 128,
              "minLength": 1,
              "pattern": "^\\S(.*\\S)?$",
              "title": "External Ref",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/PutTenantRequest"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tenant"
                }
              }
            },
            "description": "Successful Response"
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Tenant"
                }
              }
            },
            "description": "The tenant was created."
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "put_tenant",
        "tags": [
          "tenants"
        ]
      }
    },
    "/v1/uploads": {
      "post": {
        "description": "Stage bytes for document operations and return a handle.\n\nCost class: **fast** (upload I/O only; no processing units charged here).\n\nThe returned ``upload_id`` is passed as ``{\"type\": \"upload\", \"upload_id\":\n\"<id>\"}`` in any subsequent document-operation request.  Uploads are\nretained until explicit deletion of the upload, consuming jobs or tenant.\nZero retention refuses standalone uploads with ``422 invalid_request``;\nuse a workspace bound to your own S3 or Azure storage.\n\nUploads are workspace-free: this is the entry point for callers that want\nto use granular operations without onboarding to the full ingestion model.",
        "operationId": "create_upload_v1_uploads_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_create_upload_v1_uploads_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ndi_service__app__platform_api__document_operations__schemas__UploadResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_upload",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/uploads/{upload_id}": {
      "delete": {
        "description": "Erase an unused upload. A used upload must be removed by deleting its consuming jobs.",
        "operationId": "delete_upload_v1_uploads__upload_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "upload_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Upload Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "delete_upload",
        "tags": [
          "document-operations"
        ]
      }
    },
    "/v1/usage": {
      "get": {
        "description": "Aggregate job units for a billing period. Cost class: fast.\n\n``credits`` is what the period bills; ``units`` are measured work, including\nfailed and cancelled jobs that are not billed. The admission allowance also counts failed and cancelled\nwork and in-flight reservations, so a ``quota_exceeded`` ``credits_used`` can\nexceed ``credits_total``.\n\n``pages`` and ``bytes_ingested`` aggregate the per-job processing volume\nthe workers record at completion time. ``credits`` sums only jobs whose\nusage is final; ``unfinalized_jobs`` counts the ones still open.",
        "operationId": "get_usage_v1_usage_get",
        "parameters": [
          {
            "description": "Start of the billing window, inclusive.",
            "in": "query",
            "name": "period_start",
            "required": true,
            "schema": {
              "description": "Start of the billing window, inclusive.",
              "format": "date",
              "title": "Period Start",
              "type": "string"
            }
          },
          {
            "description": "End of the billing window, inclusive.",
            "in": "query",
            "name": "period_end",
            "required": true,
            "schema": {
              "description": "End of the billing window, inclusive.",
              "format": "date",
              "title": "Period End",
              "type": "string"
            }
          },
          {
            "description": "Restrict to one workspace.  Omit to aggregate all jobs for this API key.",
            "in": "query",
            "name": "workspace_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "uuid",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to one workspace.  Omit to aggregate all jobs for this API key.",
              "title": "Workspace Id"
            }
          },
          {
            "description": "Aggregation key: calendar day, job kind, or workspace. `tenant` is for a partner key sent without `X-NDI-Tenant`: one bucket per child tenant, keyed by its `external_ref`.",
            "in": "query",
            "name": "group_by",
            "required": false,
            "schema": {
              "default": "day",
              "description": "Aggregation key: calendar day, job kind, or workspace. `tenant` is for a partner key sent without `X-NDI-Tenant`: one bucket per child tenant, keyed by its `external_ref`.",
              "enum": [
                "day",
                "kind",
                "workspace",
                "tenant"
              ],
              "title": "Group By",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ndi_service__app__platform_api__operations__schemas__UsageResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_usage",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/usage/overview": {
      "get": {
        "description": "Dashboard figures for documents processed, in-flight jobs, and latency.\n\nCost class: fast. Documents are succeeded document-operation jobs\n(parse / split / classify / categorize / extract / ground / qa_file)\nfinished in the window. Active and queued counts are a point-in-time\nsnapshot of every job kind. The series is zero-filled so a chart can\nplot it without filling gaps.",
        "operationId": "get_usage_overview_v1_usage_overview_get",
        "parameters": [
          {
            "description": "Rolling window ending today (UTC): 7, 30, or 90 days.",
            "in": "query",
            "name": "window",
            "required": false,
            "schema": {
              "default": "7d",
              "description": "Rolling window ending today (UTC): 7, 30, or 90 days.",
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "title": "Window",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageOverviewResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_usage_overview",
        "tags": [
          "operations"
        ]
      }
    },
    "/v1/workspaces": {
      "get": {
        "description": "Page through the caller's workspaces, oldest-first. Cost class: fast.\n\nKeyset-paginated on ``(created_at, id)``; the cursor is opaque.",
        "operationId": "list_workspaces_v1_workspaces_get",
        "parameters": [
          {
            "description": "Case-insensitive name filter.",
            "in": "query",
            "name": "name_contains",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Case-insensitive name filter.",
              "title": "Name Contains"
            }
          },
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_Workspace_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_workspaces",
        "tags": [
          "workspaces"
        ]
      },
      "post": {
        "description": "Provision a new workspace. Cost class: fast.\n\nEvery field has a sensible default so a caller who knows nothing creates a\nworking workspace with just a name. The workspace is immediately usable for\ningestion after this call; no activation step is needed.\n\nRetry with the same Idempotency-Key and body after an interrupted response.",
        "operationId": "create_workspace_v1_workspaces_post",
        "parameters": [
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWorkspaceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_workspace",
        "tags": [
          "workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}": {
      "delete": {
        "description": "Permanently delete a workspace and all of its content. Cost class: job.\n\nThis is an irreversible, tenant-wide destructive action.\n\n``confirm_name`` must equal the workspace's name exactly; this is a\ndeliberate friction point, not a formality. The teardown (storage prefix,\nsearch index, graph nodes) runs asynchronously; poll the returned job.\n\n**Not exposed over MCP.** An irreversible tenant-wide deletion does not\nbelong in a model's action space. Surface suppression is a per-method\nregistry flag on the MCP descriptor, not a special case at this layer.",
        "operationId": "delete_workspace_v1_workspaces__workspace_id__delete",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteWorkspaceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceDeleteJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "delete_workspace",
        "tags": [
          "workspaces"
        ]
      },
      "get": {
        "description": "Read one workspace. Cost class: fast.",
        "operationId": "get_workspace_v1_workspaces__workspace_id__get",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_workspace",
        "tags": [
          "workspaces"
        ]
      },
      "patch": {
        "description": "Change a workspace's mutable configuration. Cost class: fast.\n\nPresence-aware, and whole-block: an omitted field is left alone, a supplied\none replaces its block entirely. Read the workspace, edit the block, send it\nback — partial blocks fall back to the schema defaults, which is how a caller\nflipping ``auto_build`` would otherwise wipe its own exclusion rules.\n\nGraph builds are explicit by default: a build happens when\n``POST /v1/workspaces/{id}/knowledge-graph/builds`` asks for one. Turning\n``knowledge_graph.auto_build`` on hands that trigger to ingestion instead, for\na workspace that wants a graph over everything it ingests and accepts the bill\nfor one per ingestion. Either way a build already in flight is unaffected —\ncancel it if that is what you meant.\n\n``currency`` follows the same whole-block rule, so ``{}`` is how its policy is\ncleared. Setting ``currency.default`` changes how the *next* ingestion reads\namounts marked with a symbol that names several currencies ($, ¥, kr);\namounts already extracted as ambiguous stay that way until their file is\nre-ingested, because the catalog records what a past extraction could read.\n\nOrdinary workspace names are mutable without changing identity or storage;\nplatform-provisioned workspace names remain fixed.\nThe domain and label list are deliberately not mutable here. They are part of the versioned config record stamped\nonto every derived artifact, so editing them in place would re-describe\nmaterial that was derived under the old one.",
        "operationId": "update_workspace_v1_workspaces__workspace_id__patch",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWorkspaceRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "update_workspace",
        "tags": [
          "workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/artifacts/content": {
      "get": {
        "description": "Stream current artifact bytes by exact workspace-relative path.",
        "operationId": "get_artifact_content_v1_workspaces__workspace_id__artifacts_content_get",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Exact workspace-relative path of a live source, derivative, or query-result artifact.",
            "in": "query",
            "name": "path",
            "required": true,
            "schema": {
              "description": "Exact workspace-relative path of a live source, derivative, or query-result artifact.",
              "maxLength": 1024,
              "minLength": 1,
              "pattern": "^[^/]",
              "title": "Path",
              "type": "string"
            }
          },
          {
            "description": "Optional single HTTP byte range, for example `bytes=0-1023`.",
            "in": "header",
            "name": "Range",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional single HTTP byte range, for example `bytes=0-1023`.",
              "title": "Range"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_artifact_content",
        "tags": [
          "artifacts"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/artifacts/rows": {
      "get": {
        "description": "One page of a parquet, csv or jsonl artifact's rows, in file order, by exact workspace-relative path.",
        "operationId": "get_artifact_rows_v1_workspaces__workspace_id__artifacts_rows_get",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Exact workspace-relative path of a live source, derivative, or query-result artifact.",
            "in": "query",
            "name": "path",
            "required": true,
            "schema": {
              "description": "Exact workspace-relative path of a live source, derivative, or query-result artifact.",
              "maxLength": 1024,
              "minLength": 1,
              "pattern": "^[^/]",
              "title": "Path",
              "type": "string"
            }
          },
          {
            "description": "File row number of the first row in the page, 0-based.",
            "in": "query",
            "name": "start_row",
            "required": false,
            "schema": {
              "default": 0,
              "description": "File row number of the first row in the page, 0-based.",
              "minimum": 0,
              "title": "Start Row",
              "type": "integer"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Ascending, non-overlapping inclusive row ranges to read instead of a contiguous window, e.g. '3-3,17-19'. Replaces start_row/limit; the ranges may cover at most as many rows as the page limit allows.",
            "in": "query",
            "name": "ranges",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 8400,
                  "pattern": "^\\d+-\\d+(,\\d+-\\d+)*$",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Ascending, non-overlapping inclusive row ranges to read instead of a contiguous window, e.g. '3-3,17-19'. Replaces start_row/limit; the ranges may cover at most as many rows as the page limit allows.",
              "title": "Ranges"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArtifactRowsPage"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_artifact_rows",
        "tags": [
          "artifacts"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/automatic-search": {
      "post": {
        "description": "Answer one query with fact search or the automatic search agent. Cost class: **job**.\n\nWith ``mode`` ``auto`` (the default), the service reads the query and optional\ncontext before retrieval and chooses a one-pass fact search for focused\nlookups, or an agent that locates the pages and tables it needs with a\nnavigator over the workspace's files (on a workspace in a bring-your-own\nbucket or customer storage, by searching it), then reads documents, queries\ntables, and selects documents from the metadata catalog. When it chooses fact search and fact\nsearch cannot settle the question (it finds no answer while a table it was\ngiven was not read whole, such as a Parquet table or one too large to read, or\nit cites nothing, grades its answer low or speculative, or fails), the agent\nanswers instead: ``routing.selected`` stays ``fact`` and ``routing.final``\nreads ``agent``. When fact search finds no answer in material it read whole,\nthat is the answer, with no hand-over.\nIn any mode, a query that asks for nothing (a keyboard mash, say) and none of\nwhose words a document contains is answered so without a search or a charge.\n``mode`` ``fact`` or ``agent`` runs that route directly, with no\nrouting step to bill and no hand-over. This single-shot route does not\nask clarification questions. Every route enforces\nthe caller's access and its scope: ``path_prefix`` and ``paths`` resolve to one\nfile set, the same one fact search and the agent (its catalog commands included)\nfilter by. Each ``paths`` entry must name a visible uploaded source file.\n\nThe result contains the chosen route's output and its owning `output_job_id`,\nplus routing details. When the agent answers from the catalog, its output also\ncarries the catalog table, whose `next_cursor` continues through\n`filtered-search` with a page request, without another routing decision.",
        "operationId": "automatic_search_v1_workspaces__workspace_id__automatic_search_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AutomaticSearchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutomaticSearchJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "automatic_search",
        "tags": [
          "intelligent-search"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/deep-search": {
      "post": {
        "deprecated": true,
        "description": "Run an agentic search over a workspace. Cost class: **job**.\n\nThe caller receives a ``202`` with a queued\n:class:`~ndi_service.app.platform_api.results.Job` immediately, and polls\n``GET /jobs/{id}`` for the result once the job succeeds.\n\nEvery run uses one configuration: a reasoning engine with a thinking\nbudget, the internal CLI tool surface, and the workspace's knowledge graph\nwhen one is built (the 2026-09 five-lane evaluation picked it as the most\naccurate lane).\n\nOne implementation serves every scope: the source-level\nagent (``deep_search_v2``). It browses, reads, and computes over the\nuploaded files exactly as an API caller would, writes its own SQL over the\ntables in scope, and every executed statement lands on the result as a\nreceipt (``sql_receipts``) — a figure and the query behind it travel\ntogether. (Jobs created before the 2026-09 consolidation may carry the\nretired classic loop's ``intelligent_search`` kind; they stay readable via\n``GET /jobs``.)\n\nScope never changes the configuration: ``paths`` scopes the run to exactly\nthose uploaded files — every tool the agent runs (search, listings, reads,\nask-file, SQL, the shell's ``ndi`` commands) sees only them and the\ncontent ingested from them, enforced server-side against the stored job.\nEach entry must name a visible uploaded source file (``file_not_found`` /\n``access_denied`` otherwise, before any job is created). With ``path_prefix``\nthe two add up: the run covers the folder's files plus the named ones.\n\nPass the result's ``session_id`` to ask a follow-up. With the same\nfolder/file scope and access grants, the agent resumes that transcript.\nChanging either starts a fresh conversation and returns its new\n``session_id``, so prior tool results cannot cross the new scope boundary.\nOlder transcripts without a scope snapshot also restart. Classic thread\nids return ``session_not_found``; retrying the original request with its\nidempotency key still returns that historical job.\n\n``allow_clarification`` lets the agent ask instead of guessing on a genuinely\nambiguous query: the succeeded result then carries the questions in\n``clarification_questions`` (and as text in ``clarification``) with\n``answer`` null. Answer them in the same thread — send the result's\n``session_id`` with the same ``query`` and ``clarification_answers``, or with\nany refined query. Off (the default) the agent never asks back.\n\nRetrieval only: this job never grounds.  To pin a quote to a region of its\nsource document, call document-operations ``ground`` on the file the\ncitation names with its quote as the target text — separately, and only\nfor the citations you actually need a locator for.\n\n``exhausted: true`` means the step budget ran out before the agent\nfinished — a successful, partial response, not a failure.",
        "operationId": "deep_search_v1_workspaces__workspace_id__deep_search_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeepSearchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeepSearchJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "deep_search",
        "tags": [
          "intelligent-search"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/fact-search": {
      "post": {
        "deprecated": true,
        "description": "Run the fixed single-shot search pipeline over a workspace. Cost class: **job**.\n\nOne retrieval pass (hybrid search, plus the knowledge graph when the\nworkspace has one, fused when both legs return candidates), targeted page\nreads or retrieved passages for prose (specialized engines for tables or\nimages), then one answering pass — so it returns in seconds where\n``deep-search`` may take minutes.  The caller receives a ``202`` with a\nqueued :class:`~ndi_service.app.platform_api.results.Job` and polls\n``GET /jobs/{id}`` for the\n:class:`~ndi_service.app.platform_api.results.IntelligentSearchResult` —\nthe identical result shape ``deep-search`` lands, evidences and coverage\nincluded.\n\nSingle-shot: a fact-search run keeps no conversation, so the result's\n``session_id`` is always ``null`` and the request body has no\n``session_id`` field.  For a thread you can ask follow-ups in, call\n``deep-search``.  It always answers — the result carries a direct grounded\n``answer``, with ``reasoning`` stating how the pipeline read the query —\nand never asks back: the body has no ``allow_clarification`` either (a\nfixed pipeline has no agent who could pose the question).\n\n``paths`` scopes the run to exactly those uploaded files: every retrieval\nleg sees only them and the content ingested from them, enforced\nserver-side against the stored job. Each entry must name a visible\nuploaded source file (``file_not_found`` / ``access_denied`` otherwise,\nbefore any job is created). With ``path_prefix`` the two add up: the run\ncovers the folder's files plus the named ones.\n\nRetrieval only: this job never grounds.  To pin a quote to a region of its\nsource document, call document-operations ``ground`` on the file the evidence\nnames (``source_file_id``) with its ``quote`` as the target text.",
        "operationId": "fact_search_v1_workspaces__workspace_id__fact_search_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FactSearchRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntelligentSearchJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "fact_search",
        "tags": [
          "intelligent-search"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/files": {
      "get": {
        "description": "List source files with exact totals and access-filtered coverage.\n\nCost class: **fast** (structured-metadata predicates only; no index lookup).\n\nThe sanctioned completeness instrument: ``total_count`` is exact and\naccess-filtered; ``coverage`` says how many candidates the access gate\nwithheld and which labels would have been needed.  A caller that cannot\nreconcile ``total_count`` with their own ledger knows the gap is\nlabelled content rather than a missing file.",
        "operationId": "list_files_v1_workspaces__workspace_id__files_get",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Restrict to paths starting with this prefix.",
            "in": "query",
            "name": "path_prefix",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to paths starting with this prefix.",
              "title": "Path Prefix"
            }
          },
          {
            "description": "Restrict to these ingestion statuses.",
            "in": "query",
            "name": "ingestion_status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "items": {
                    "$ref": "#/components/schemas/IngestionStatus"
                  },
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to these ingestion statuses.",
              "title": "Ingestion Status"
            }
          },
          {
            "description": "Restrict to these categories.",
            "in": "query",
            "name": "categories",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to these categories.",
              "title": "Categories"
            }
          },
          {
            "description": "Restrict to these file extensions.",
            "in": "query",
            "name": "file_types",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Restrict to these file extensions.",
              "title": "File Types"
            }
          },
          {
            "description": "Only files updated after this timestamp.",
            "in": "query",
            "name": "modified_after",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only files updated after this timestamp.",
              "title": "Modified After"
            }
          },
          {
            "description": "Only files updated before this timestamp.",
            "in": "query",
            "name": "modified_before",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only files updated before this timestamp.",
              "title": "Modified Before"
            }
          },
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileListPage"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_files",
        "tags": [
          "files"
        ]
      },
      "post": {
        "description": "Upload a source file into the workspace. Cost class: **job**.\n\nThe one route with two credentials: the tenant's ``X-API-Key``, or a\nshort-lived ``X-Upload-Token`` grant minted by ``create_upload_grant`` —\nwhich is how a customer's end client uploads directly without ever\nholding the key. A grant redeems the multipart path only, within the\nconstraints frozen into it (workspace, optional pinned path, byte cap).\n\nTwo content paths, per the ``UploadFileRequest`` contract:\n\n* ``multipart/form-data`` — file bytes in a ``file`` part, request\n  parameters as a JSON string in a ``metadata`` form field.\n* ``application/json`` — an ``UploadFileRequest`` body whose ``source``\n  carries a ``UrlSource``; the bytes are fetched server-side and then\n  take the exact same storage/ledger path as multipart.\n\n**Upload does NOT ingest.**  The file lands with\n``ingestion_status = discovered`` and is not searchable.  Making it\nsearchable requires a separate ``POST .../ingestions`` call.  This keeps\nthe cost model honest: a caller can upload a thousand files and choose to\ningest fifty.",
        "operationId": "upload_file_v1_workspaces__workspace_id__files_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_upload_file_v1_workspaces__workspace_id__files_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadFileJob"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          },
          {
            "UploadGrantHeader": []
          }
        ],
        "summary": "upload_file",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/files/{file_id}": {
      "delete": {
        "description": "Soft-delete a file and run the cross-representation cascade as a job.\n\nThe file is soft-deleted (``deleted_at`` stamped) so lineage questions\nstay answerable after the cascade.  The cascade job then retires index\ndocuments and output rows, drops the sibling folder from storage, cancels\nin-flight ingestion jobs that name the file, and independently re-checks\nevery representation.  ``DeleteFileResult.counts`` exist so this is\nauditable rather than assumed, and ``verified: false`` is a failed cascade\nthat must alert.",
        "operationId": "delete_file_v1_workspaces__workspace_id__files__file_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteFileJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "delete_file",
        "tags": [
          "files"
        ]
      },
      "get": {
        "description": "Return a file plus a short-lived presigned download URL. Cost class: **fast**.\n\nNo separate ``GET .../content`` route: the presigned URL keeps raw bytes\noff the API path.  The URL expires after ``DOWNLOAD_URL_TTL_SECONDS``\nseconds; fetch it promptly.\n\nA direct read of a named file is the one case where hard denial\n(``403 access_denied``) is correct: the caller named the file, so there\nis nothing to narrow and nothing to infer — they already knew it existed.",
        "operationId": "get_file_v1_workspaces__workspace_id__files__file_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_file",
        "tags": [
          "files"
        ]
      },
      "put": {
        "description": "Replace a file's content atomically. Cost class: **job**.\n\nThe replacement is atomic from a reader's perspective: the old version is\nstamped ``replaced_at`` and the new version is live in the same commit.\n\nRe-ingests only if the file was ingested before (``ingestion_status``\nbecomes ``stale``); a never-ingested file returns to ``discovered``.\nThe actual cascade (retiring outputs, queuing re-ingestion) is the\n``dispatch`` seam in the job service.",
        "operationId": "replace_file_v1_workspaces__workspace_id__files__file_id__put",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_replace_file_v1_workspaces__workspace_id__files__file_id__put"
              }
            }
          }
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReplaceFileJob"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "replace_file",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/files/{file_id}/metadata": {
      "get": {
        "description": "Return ingestion-derived metadata for a file. Cost class: **fast**.\n\n``representations`` answers \"is this file actually searchable right now\",\nwhich ``ingestion_status`` alone cannot: a file can be ingested while its\ngraph generation is still building.",
        "operationId": "get_file_metadata_v1_workspaces__workspace_id__files__file_id__metadata_get",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileMetadata"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_file_metadata",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/files/{file_id}/outputs/{output_id}": {
      "get": {
        "description": "Return a live derived-file output plus short-lived download URLs. Cost class: **fast**.\n\nOnly ``derived_file`` outputs live as objects in the workspace store.\nSearch-index and knowledge-graph outputs carry opaque keys and cannot be\nfetched this way.",
        "operationId": "get_file_output_v1_workspaces__workspace_id__files__file_id__outputs__output_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "output_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Output Id",
              "type": "string"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArtifactOutputDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_file_output",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/files/{file_id}/outputs/{output_id}/members": {
      "get": {
        "description": "List the objects inside a derived-output folder, each presigned inline. Cost class: **fast**.\n\nA recording's ``frames/`` folder is registered as a single ``derived_file``\noutput, not one row per frame, so this browses the folder straight from\nstorage. A leaf output (a single markdown/json file) has no members and\nreturns an empty page.",
        "operationId": "list_output_members_v1_workspaces__workspace_id__files__file_id__outputs__output_id__members_get",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "output_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "Output Id",
              "type": "string"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Members to skip, for paging a large folder.",
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Members to skip, for paging a large folder.",
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ArtifactOutputMembersPage"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "list_output_members",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/files/{file_id}/versions": {
      "get": {
        "description": "Return a newest-first page of version history for a file. Cost class: **fast**.\n\nMetadata only — bytes from superseded versions are not retained by\ndefault (customer opt-in).  ``is_current`` is ``true`` only on the latest\nversion.",
        "operationId": "get_file_versions_v1_workspaces__workspace_id__files__file_id__versions_get",
        "parameters": [
          {
            "in": "path",
            "name": "file_id",
            "required": true,
            "schema": {
              "format": "uuid",
              "title": "File Id",
              "type": "string"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
            "in": "query",
            "name": "cursor",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Opaque cursor from a previous page's `next_cursor`. Omit for the first page.",
              "title": "Cursor"
            }
          },
          {
            "description": "Rows per page.",
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 50,
              "description": "Rows per page.",
              "maximum": 200,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page_FileVersion_"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_file_versions",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/filtered-search": {
      "post": {
        "description": "Run a structured filter/rank/count query over the workspace's metadata catalog. Cost class: **job**.\n\nSend ``{type: \"query\", query, context?, path_prefix?, paths?, allow_clarification?}``\nto start a search. ``path_prefix`` and ``paths`` resolve to one file set: only\ncatalog entries extracted from those files can match. Each ``paths`` entry must\nname a visible uploaded source file. Then an agent translates the request into a validated catalog\nquery, and the result is a table — typed columns, matching components as\nrows (each named by its uploaded file), an exact ``total_matches``, and\nevidence citations per extracted value. Count-style questions return the\ntotal with no rows; \"top N\" questions return exactly N rows with the\npre-cutoff total. With ``allow_clarification`` set, a genuinely ambiguous request\nmay come back as a rejection instead: the succeeded result carries one\nquestion in ``clarification`` (no rows, no ``applied_query``, ``exhaustive``\nfalse) — filtered search keeps no session, so answer it by sending a new\ninitial query.\n\nSend ``{type: \"page\", cursor}`` with an earlier result's ``next_cursor``\nto fetch the next page. Pages re-execute the original query against the\n**current** catalog under your current access — no agent runs, and\nconcurrent ingestion or deletion may shift later pages (the result's\n``catalog_drifted`` says the underlying data changed). Only the API key\nthat ran the original query may page it; an expired or purged parent job\nreturns ``invalid_request``.\n\nRead ``exhaustive`` before treating a result as a census: when false, the\nmatches shown are valid but completeness is not guaranteed (uncataloged\nfiles in scope, degraded extractions, or a residual content condition).\nRead ``field_readability`` alongside it: a non-empty entry means the\npredicate could not be evaluated on part of the population, so an empty or\nthin result may reflect unreadable data rather than absence.\nMonetary values always carry their ISO currency and are never converted;\ncomparing amounts across currencies is unsupported in this version.",
        "operationId": "filtered_search_v1_workspaces__workspace_id__filtered_search_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/InitialFilteredSearch"
                  },
                  {
                    "$ref": "#/components/schemas/FilteredSearchPage"
                  }
                ],
                "title": "Body"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FilteredSearchJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "filtered_search",
        "tags": [
          "filtered-search"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/ingestions": {
      "post": {
        "description": "Queue an ingestion run for one file, a batch, or an entire folder.\n\nCost class: **job** (pipeline compute per file; billed on completion).\n\nPass a :class:`~ndi_service.app.platform_api.contracts.IngestionSelection`\nto say what to process:\n\n* ``{\"type\": \"file_ids\", \"file_ids\": [...]}`` — explicit file list.\n* ``{\"type\": \"path_prefix\", \"path_prefix\": \"reports/\"}`` — a folder;\n  ``stale_only=true`` restricts the run to files whose hash diverged.\n\nThe ingestion lane (PDF, Excel, audio, …) is chosen per file from its type;\na caller does not name a lane.\n\n**Per-file outcomes, not a single verdict.** A file already ingested at\nthe same hash is ``skipped_unchanged`` (free) unless ``reingest_unchanged``\nis set. A valid zero-row raw Parquet file is ``skipped_empty`` (free) and\nproduces no searchable table. One corrupt file in a folder of 400 does not\nfail the run. It appears as a ``failed`` entry in ``result.outcomes``.\nA job where every attempted file failed is ``failed``. Its ``error.code``\nis taken from the files, and ``error.detail`` carries the per-file reasons.\nThat job has no ``result``. Partial failures stay outcomes on a succeeded job.\n\nThis is the **only call that makes files searchable**. Uploading a file to\nthe workspace ledger registers it; ingesting it builds the representations\n(search index, knowledge-graph nodes) that queries read.",
        "operationId": "ingest_v1_workspaces__workspace_id__ingestions_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IngestRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestionJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "ingest",
        "tags": [
          "ingestion"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/je-testing": {
      "post": {
        "description": "Run journal-entry testing over a workspace's ledger package. Cost class: **job**.\n\nThe caller receives a ``202`` with a queued\n:class:`~ndi_service.app.platform_api.results.Job` immediately and polls\n``GET /jobs/{id}`` for the\n:class:`~ndi_service.app.platform_api.results.JetResult`.\n\nThe agent orients itself in the tables the workspace holds, writes SQL over\nthem itself, and answers with ``sql_receipts``: every statement it ran, the\ntables each one registered (path, tab, and the view name the SQL used), and\na bounded result. A figure in the answer is meant to be readable out of one\nof those receipts, and a receipt carries everything needed to re-run it.\n\n``paths`` scopes the run to exactly the files of the package under test;\n``path_prefix`` scopes it to a folder, and the two add up: the run tests\nthe folder's files plus the named ones. Omit both to test the whole workspace: the agent orients\nover every queryable file the caller can see and finds the ledger package\nitself, the same way ``deep-search`` behaves when unscoped. A run keeps its\nconversation: pass the result's ``session_id`` on a later request to ask a\nfollow-up in the same thread.\n\n``reasoning_effort`` controls the thinking budget without changing the\nengine. Omit it for the route's default; null keeps the catalogue prescription.\n\n``allow_clarification`` lets the agent stop and ask instead of answering —\nearly, for what the data cannot tell it (a threshold, the period or entity in\nscope, the client's definition of a term), or mid-run, for an ambiguity the\nwork turned up. The succeeded result then carries the questions in\n``clarification_questions`` with ``answer`` null. Answer them on the same\n``session_id`` with the same ``query`` and ``clarification_answers``, or with\nany follow-up query. Off (the default) the agent never asks.\n\n``exhausted: true`` means the step budget ran out before the procedure\nfinished — a successful, partial response, not a failure.",
        "operationId": "je_testing_v1_workspaces__workspace_id__je_testing_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/JeTestingBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JeTestingJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "je_testing",
        "tags": [
          "je-testing"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/knowledge-graph/builds": {
      "post": {
        "description": "Build (or rebuild) the workspace's knowledge graph from its ingested files.\n\nCost class: **job** (corpus-level extraction and entity resolution; billed on\ncompletion).\n\nThe graph is built over every **ingested** file in the workspace at once —\nentity resolution links entities *across* documents, so it cannot be a per-file\noperation the way parsing or categorization are. Files that are not yet ingested\nare not in the corpus. Ingest them first, then build. A workspace with no\ningested files is refused with ``invalid_request`` before a job is created.\nThat check runs after an idempotent replay, so a retry of a build that\nalready started still returns the original job. A workspace whose ingested\nfiles are all excluded by graph rules still starts a job. The workflow\nfails that job. A rebuild resumes from the durable store, re-paying only\nfor what changed since the last build. ``force`` clears the store and\nrebuilds from scratch.\n\nOnce built, query the graph with the ``kg-info`` / ``kg-search`` / ``kg-walk``\ncontext tools. A file's ``representations.knowledge_graph`` reads true once a\nbuild that covered it has finalized.",
        "operationId": "build_knowledge_graph_v1_workspaces__workspace_id__knowledge_graph_builds_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KnowledgeGraphBuildRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KnowledgeGraphBuildJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "build_knowledge_graph",
        "tags": [
          "knowledge-graph"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/qa": {
      "post": {
        "description": "Ask a question about a workspace, as one turn of a conversation. Cost class: **job**.\n\nEvery turn runs the automatic search agent on its own — no router, no fixed\npipeline, no opening search. The agent finds what the turn needs itself, in\nthe light of the conversation so far: it asks a navigator over the\nworkspace's files, sections and pages, or, on a workspace in a\nbring-your-own bucket or customer storage, searches it. It then reads\ndocuments, queries tables, and selects documents from the metadata catalog\nuntil it can answer. Every tool enforces\nthe caller's access and the conversation's scope: ``path_prefix`` and\n``paths`` resolve to one file set.\n\nPass a result's ``session_id`` to ask a follow-up: the agent resumes the\nconversation, so \"and for 2023?\" or \"why?\" means what it means in context.\nWhen a question is genuinely ambiguous the agent may ask back instead\n(``allow_clarification``, on by default): the result then carries\n``clarification_questions`` with ``answer`` null; reply with\n``clarification_answers`` and the same ``session_id``, or rephrase.\n\nA conversation's first question that asks for nothing (a keyboard mash, say)\nand none of whose words a document contains is answered so without running\nthe agent or a charge, and starts no conversation.\n\nThe result is the agent's answer — citations, SQL receipts, confidence — plus,\nwhen it answered from a catalog query, the catalog table, whose\n``next_cursor`` continues through ``filtered-search``.",
        "operationId": "qa_v1_workspaces__workspace_id__qa_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QaRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QaJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "qa",
        "tags": [
          "intelligent-search"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/reconciliations": {
      "post": {
        "description": "Detect divergence between storage and the file ledger; optionally act on it.\n\nCost class: **job** (storage listing + hash comparison; billed on completion).\n\nReconciliation compares the customer-visible storage tree against the ledger\nand records the result there. The scan itself never modifies stored bytes or\nderived representations. It marks:\n\n* ``discovered`` — objects in storage with no ledger row.\n* ``stale`` — rows whose ``observed_hash`` no longer matches the stored object.\n* ``orphans`` — rows whose object is gone from storage.\n\nSet ``auto_ingest=true`` to chain a ``POST /workspaces/{id}/ingestions``\nautomatically when divergence is found. Without it, reconciliation still\nupdates the ledger but starts no ingestion. The ``ingestion_job_id`` in the\nresult points to that job so you can poll it separately.\n\n``selection.stale_only`` on the chained ingestion is the routine case:\nit re-ingests exactly the stale files and is a no-op when nothing diverged.\n\n``path_prefix`` scopes the scan; omit it (or pass ``null``) to scan the\nwhole workspace.",
        "operationId": "reconcile_v1_workspaces__workspace_id__reconciliations_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReconcileRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Terminal job or idempotent replay of the original job; read status and replayed.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReconciliationJob"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "reconcile",
        "tags": [
          "ingestion"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/shares": {
      "get": {
        "description": "Return the workspace owner and every explicitly shared user.",
        "operationId": "get_workspace_shares_v1_workspaces__workspace_id__shares_get",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceShares"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_workspace_shares",
        "tags": [
          "workspaces"
        ]
      },
      "put": {
        "description": "Replace the complete explicit share set in one atomic write.",
        "operationId": "replace_workspace_shares_v1_workspaces__workspace_id__shares_put",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceWorkspaceSharesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceShares"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "replace_workspace_shares",
        "tags": [
          "workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/stats": {
      "get": {
        "description": "Compute workspace content statistics. Cost class: fast.\n\nReturns file counts, byte totals, ingestion timestamps, and expiry\ninformation — enough for a caller to determine whether the workspace needs\ningestion or a re-ingest without paging through ``list_files``.\n\n``kg_nodes`` / ``kg_edges`` describe the workspace's published knowledge\ngraph, and are zero until a build has finished one. They come from the\nbuild's own record rather than the graph itself, so this stays a fast read;\nan unreachable graph store reports zero rather than failing the request.",
        "operationId": "get_workspace_stats_v1_workspaces__workspace_id__stats_get",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceStats"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "get_workspace_stats",
        "tags": [
          "workspaces"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/catalog": {
      "post": {
        "description": "The metadata catalog ingestion extracted from every document: its tables, or one SELECT's rows.\n\n**Cost class: fast.** Answers inline: no job, no credits. Without ``sql``: one table per document\ntype the workspace holds (invoices, contracts, statements...) with its typed columns, plus\n``catalog_document`` over every record. With ``sql``: one read-only SELECT over those tables, its rows\ncapped and ``truncated`` set when cut. A refused or failing statement answers ``invalid_request`` with\nthe reason; so does a workspace whose catalog is too large to query whole.\n\nA record is one document section, spreadsheet tab, recording or JSON section, never one printed line:\nthe entries a listing, register or ledger prints (each credit note in a credit-note report) are not\nrecords of their own. The listing is one record; read it with ``read-file``, or query a tab's rows\nwith ``run-sql``. Every record carries ``source_path``, the path the other file tools take.",
        "operationId": "catalog_v1_workspaces__workspace_id__tools_catalog_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CatalogToolRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogToolResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "catalog",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/file-metadata": {
      "post": {
        "description": "Describe one uploaded file without opening it: what it is, its category, and the parts you can ask about.\n\n**Cost class: fast.**\n\n``path`` is the file's full path relative to the workspace root, exactly\nas it was uploaded and as ``folder-metadata``, ``GET .../files`` and search\nresults (``source_path``) print it — for example\n``evidence/doc-7f83/contract.pdf``. A bare file name (``contract.pdf``), a\nfolder, a file id, or a path that starts with the workspace id is not\nfound. ``file_not_found`` is final for that value: do not retry it or guess\nvariants — list the folder with ``folder-metadata`` (``name_contains=`` a\npart of the name) and use the path it prints.\n\nThe response gives the file's ``category``, a ``summary`` of its first\nsection or tab, page or tab counts, and its ``components``: each section,\ntab, image or recording with its own summary, categories, page range or\ntable shape, and ``key_terms`` — keywords whose role the source states\n(who a name is, what a date marks). A recording reports its duration.\n``readable`` means ``qa-file`` can answer from the component's text;\n``queryable`` means it is a table ``query-tables`` can compute over. Pass a\ncomponent's ``name`` as ``component`` to scope either tool to it.\n\n``component`` narrows this response to one section or tab by name; a name\nthat matches nothing is refused with ``invalid_request`` listing the valid\nnames. A file that is not ingested yet answers 200 with its\n``ingestion_status`` and no components; a failed one carries\n``ingestion_error``.",
        "operationId": "file_metadata_v1_workspaces__workspace_id__tools_file_metadata_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FileMetadataRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileMetadataToolResponse"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "file_metadata",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/folder-metadata": {
      "post": {
        "description": "List one folder of the workspace: file counts, categories, subfolders, and the files' exact paths.\n\n**Cost class: fast.**\n\nExplore in steps instead of listing everything at once:\n\n1. Call with the defaults on ``/`` (the workspace root): the folder's own\n   files plus one summary per subfolder (file count, top categories,\n   failed-ingestion count).\n2. Descend with ``directory=<folder>``, or narrow with ``name_contains=``\n   (find a file by part of its name), ``category=``, ``ingestion_status=``\n   (e.g. ``failed``) or ``kind=``. Counts and listing narrow together, and\n   a narrow covers the whole subtree unless ``recursive=false`` is sent.\n3. Pass a ``file_entries[].path`` to ``file-metadata`` to see what is inside\n   that file, then ask with ``qa-file`` or ``query-tables``.\n\nEvery path is relative to the workspace root and never includes the\nworkspace id. ``name_contains`` finds files by what they are called — files\nwhose ingestion failed included; the search tools find them by what they\ncontain.\n\nA ``directory`` that names a file is refused with ``invalid_request``\npointing at ``file-metadata``. An unfiltered call that matches nothing\nanswers with a ``hint`` naming the nearest existing folder and what it\nholds, so a mistyped folder is not a dead end.\n\n``file_entries`` comes one ``page_size`` page at a time, sorted by path;\n``files_truncated`` reports a cut — resume with ``start_after=<last path>``\nor narrow. Counts and listing only include files the caller's access\nlabels allow; ``coverage`` says how many were withheld.",
        "operationId": "folder_metadata_v1_workspaces__workspace_id__tools_folder_metadata_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FolderMetadataRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FolderMetadataResponse"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "folder_metadata",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/locate": {
      "post": {
        "description": "Find the pages and tables that hold a piece of information.\n\n**Cost class: medium** — a few seconds on a workspace the navigator has seen; the first call after an\ningestion change reads the workspace's ingestion outputs first.\n\nA decision model walks the workspace's files, sections and pages (built at ingestion) and names the pieces to\nread, best first, with the tables to query — the locate NDI's own navigate-mode agent runs. ``text`` is that\nagent's reply, word for word. Only files the key may see are considered, cut to ``path_prefix`` / ``paths``.\n\nStateless: send back the pieces a previous call offered (``exclude``) and what you have read (``already_read``)\nto be shown something new.",
        "operationId": "locate_v1_workspaces__workspace_id__tools_locate_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocateResponse"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "locate",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/qa-file": {
      "post": {
        "description": "Answer a natural-language question about one uploaded file — document, media, image, or table.\n\n**Cost class: slow.**\n\n``path`` names an **uploaded source file** — the same full path\n``file_metadata`` takes, exactly as ``folder_metadata`` lists it; a bare\nfile name is not found, and a workspace-internal path is refused with\n``invalid_request``.\n\nThe engine is picked from what the file (or the selected component) *is*:\nan image goes to vision QA, and text — of any length — to a recursive LLM\nbuilt for long documents.  A file with several parts (a pdf split into\nsections, a workbook with several tabs, a recording with attachments) or\nwith rows (a spreadsheet tab, a csv/parquet/jsonl upload, a pdf's long\ntable) is worked by a QA agent that searches within the file, reads the\nrelevant parts, and writes its own SQL over the file's tables.  The\nresponse's ``engine`` field reports which one ran.\n\nScope the question with ``component=<name>`` (the names ``file_metadata``\nlists) to ask about one section directly.  Use this when you need a\ndirect, cited answer about a file's contents rather than search hits.\n\nExecution survives HTTP disconnects. By default the route waits and returns\nthe original answer shape. Send ``Prefer: respond-async`` to return a Job\nimmediately, then poll its ``Location`` URL. ``Idempotency-Key`` recovers the\nsame job after a lost response. Only explicit job cancellation stops it.",
        "operationId": "qa_file_v1_workspaces__workspace_id__tools_qa_file_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "prefer",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Prefer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QaFileRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/QaFileResponse"
                    },
                    {
                      "$ref": "#/components/schemas/Job"
                    }
                  ],
                  "title": "Response Qa File V1 Workspaces  Workspace Id  Tools Qa File Post"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Durable qa-file accepted; poll the Location URL.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "qa_file",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/query-tables": {
      "post": {
        "description": "Answer a natural-language question over uploaded table files — one or several.\n\n**Cost class: slow.**\n\n``paths`` is a list of selection rows — ``{\"path\": ...}`` for a whole file,\n``{\"path\": ..., \"component\": <tab>}`` for one tab of one workbook (repeat\nthe path to select several tabs).  Every path must be a **table file** —\na spreadsheet (xlsx, xls, xlsm, xlsb, ods) or record file (csv, tsv,\nparquet, jsonl, ndjson, json); a document, media, or image path is\nrefused with ``invalid_request`` naming ``qa-file``.  Every tab is askable whatever its ingestion produced:\nselections whose tabs all have extracted rows are answered by the SQL\nengine — the answer keeps full result parquet storage outside the response\nand returns bounded previews plus authenticated workspace result-file\ncitations — while a selection holding tabs with only a rendered sheet is\nanswered by a QA agent that reads renderings and queries row extractions\ntogether (no result previews on that lane; citations quote the sheets).\n\n``component`` names are workbook-local — the same strings ``file-metadata``\nand ``filtered-search`` publish as ``component``, matched exact-name first,\nthen the unambiguous sanitized alias.  A name that matches nothing on its\nown workbook — or any ``component`` on a single-table upload\n(csv/jsonl/parquet), which has no named parts — is ``invalid_request``.  A\nselected tab with no usable content at all is reported in ``unavailable``\nrather than silently dropped.\n\nExecution survives HTTP disconnects. By default the route waits and returns\nthe original answer shape. Send ``Prefer: respond-async`` to return a Job\nimmediately, then poll its ``Location`` URL. ``Idempotency-Key`` recovers the\nsame job after a lost response. Only explicit job cancellation stops it.",
        "operationId": "query_tables_v1_workspaces__workspace_id__tools_query_tables_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "prefer",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Prefer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryTablesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/QueryTablesResponse"
                    },
                    {
                      "$ref": "#/components/schemas/Job"
                    }
                  ],
                  "title": "Response Query Tables V1 Workspaces  Workspace Id  Tools Query Tables Post"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            },
            "description": "Durable table QA accepted; poll the Location URL.",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "query_tables",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/read-file": {
      "post": {
        "description": "Read the text of one uploaded file.\n\n**Cost class: fast.**\n\n``path`` names an **uploaded source file** — the only namespace this tool\nserves.  A workspace-internal path is refused with ``invalid_request``\nnaming the uploaded file to use instead.\n\nA file with several components (a spreadsheet's tabs, a pdf's sections)\nanswers with their text concatenated in the file's own order, each part\nunder a one-line header naming the component; ``components_returned`` and\n``components_omitted`` report exactly what made it into the budget.  Scope\nthe read with ``component=<name>`` (the names ``file_metadata`` lists)\nwhen only one tab or section matters, and with ``pages`` (1-based) for\npaged documents — spreadsheets have no pages, so scope those by component\ninstead.  Images are refused — ask about them with ``qa_file``.",
        "operationId": "read_file_v1_workspaces__workspace_id__tools_read_file_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReadFileRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadFileResponse"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "read_file",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/tools/run-sql": {
      "post": {
        "description": "Run one caller-authored read-only SELECT over the workspace's tables.\n\n**Cost class: fast.** No planner and no answering agent — the statement\nruns directly in the guarded SQL engine, against every queryable tab in\nthe workspace registered as a view under the ``table_name`` that\n``file-metadata`` and the folder-metadata table census publish. Joins\nacross files are ordinary SQL joins; earlier run-sql results are\nregistered too, so a returned ``res_…`` handle can be joined, aggregated,\nor paged with LIMIT/OFFSET in the next statement.\n\nThe full result is retained as parquet whatever the preview shows —\n``result_citation.result_file.download_url`` fetches it whole. A\nstatement that is not a read, or reads an unregistered table, is refused\nwith ``invalid_request`` naming the rule broken and the registered\ntables. For a natural-language question — or when the answer should be\ncomposed and cited for you — use ``query-tables`` instead.",
        "operationId": "run_sql_v1_workspaces__workspace_id__tools_run_sql_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunSqlRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunSqlResponse"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "run_sql",
        "tags": [
          "tools"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/upload-grants": {
      "post": {
        "description": "Mint a short-lived grant an end client redeems to upload directly. Cost class: **fast**.\n\nThe customer's backend holds the API key; the end user's browser must\nnever see it. This mints an HMAC-signed token that authorizes exactly one\nthing — ``upload_file`` into this workspace, optionally pinned to one\ndestination path and a byte cap — until ``expires_at``. The holder sends\nit in the ``X-Upload-Token`` header of a multipart ``POST`` to\n``upload_url``, so the bytes travel end-client → NDI once instead of\nend-client → customer → NDI twice.\n\nThe grant is stateless (no DB row); its short TTL stands in for\nrevocation, except that revoking the minting API key kills its\noutstanding grants immediately. Where the deployment runs Redis the grant\nis additionally single-use.",
        "operationId": "create_upload_grant_v1_workspaces__workspace_id__upload_grants_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadGrantRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadGrantResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "create_upload_grant",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/upload-sessions": {
      "post": {
        "description": "Open a chunked upload for a large file. Cost class: **fast**.\n\nSame auth as ``upload_file`` — an ``X-API-Key`` or a short-lived\n``X-Upload-Token`` grant — but redeemed exactly once, here. Every later\nrequest against the session (parts, status, complete, abort) presents\nthe ``session_token`` this returns instead, in the same ``X-Upload-Token``\nheader.\n\nUpload every part with ``PUT .../upload-sessions/{session_id}/parts/{n}``\nat exactly ``chunk_size`` bytes (the final part may be shorter), then\ncall ``POST .../complete``. ``GET`` the session at any point to see which\nparts have already landed, e.g. after a dropped connection.",
        "operationId": "create_upload_session_v1_workspaces__workspace_id__upload_sessions_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUploadSessionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateUploadSessionResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          },
          {
            "UploadGrantHeader": []
          }
        ],
        "summary": "create_upload_session",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/upload-sessions/{session_id}": {
      "delete": {
        "description": "Abort a chunked upload and reclaim its staged parts. Cost class: **fast**.\n\nIdempotent: a session that already completed or was already aborted\nanswers 204 without touching anything — this only ever removes staged\n*parts*, never a landed artifact.",
        "operationId": "abort_upload_session_v1_workspaces__workspace_id__upload_sessions__session_id__delete",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Upload session identifier.",
            "in": "path",
            "name": "session_id",
            "required": true,
            "schema": {
              "description": "Upload session identifier.",
              "format": "uuid",
              "title": "Session Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "UploadSessionTokenHeader": []
          }
        ],
        "summary": "abort_upload_session",
        "tags": [
          "files"
        ]
      },
      "get": {
        "description": "Read a chunked upload's lifecycle state and landed parts. Cost class: **fast**.\n\nThe resume entry point: after a dropped connection (or a page reload),\ndiff ``parts`` against what was already sent and PUT only what is\nmissing — never re-derive part numbers, and never resend a part that\nalready landed.",
        "operationId": "get_upload_session_v1_workspaces__workspace_id__upload_sessions__session_id__get",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Upload session identifier.",
            "in": "path",
            "name": "session_id",
            "required": true,
            "schema": {
              "description": "Upload session identifier.",
              "format": "uuid",
              "title": "Session Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadSessionStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "UploadSessionTokenHeader": []
          }
        ],
        "summary": "get_upload_session",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/upload-sessions/{session_id}/complete": {
      "post": {
        "description": "Concatenate every part and write the ledger row. Cost class: **job**.\n\nRejects unless the landed parts exactly cover ``[0, total_parts)`` at\ntheir exact expected sizes — nothing about completeness is trusted on\nthe client's word. The concatenation itself runs as a job, never inline:\nthe artifact only becomes visible once it commits, exactly as\n``upload_file`` — a caller polling this job's ``status`` sees the same\ncontract either way.",
        "operationId": "complete_upload_session_v1_workspaces__workspace_id__upload_sessions__session_id__complete_post",
        "parameters": [
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Upload session identifier.",
            "in": "path",
            "name": "session_id",
            "required": true,
            "schema": {
              "description": "Upload session identifier.",
              "format": "uuid",
              "title": "Session Id",
              "type": "string"
            }
          },
          {
            "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
            "in": "query",
            "name": "wait_seconds",
            "required": false,
            "schema": {
              "default": 0,
              "description": "Bounded inline wait. 0 (the default) returns 202 immediately. Above 0 the route returns 200 with a terminal job if the work finished in time, and 202 with the still-running job if it did not. Either way, read `status`. Waiting does not change how an admitted job is counted and takes no max_concurrent_sync slot (that limits synchronous calls such as the legacy synchronous API and /v1/systemone). For retained jobs, the deployment may shorten the wait and return 202 with the running job; poll GET /v1/jobs/{job_id}. For parse, split, classify, categorize, extract and ground, a zero_retention tenant must pass wait_seconds above 0.",
              "maximum": 300,
              "minimum": 0,
              "title": "Wait Seconds",
              "type": "integer"
            }
          },
          {
            "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Use the same key to recover an earlier request. A replay returned as a Job carries Idempotent-Replayed: true and replayed: true without a new charge; Job credits keeps the original cost. Re-serving a settled inline tool answer reports zero credits for that call and also carries Idempotent-Replayed: true; a fresh re-execution after a transient failure carries no header. The key is kept with the job for replay and never cleared, so it must not contain personal data.",
              "title": "Idempotency-Key"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadSessionCompleteJob"
                }
              }
            },
            "description": "Successful Response",
            "headers": {
              "Idempotent-Replayed": {
                "description": "Present with value true only when this request replays an existing job without billing again.",
                "schema": {
                  "type": "boolean"
                }
              }
            }
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "UploadSessionTokenHeader": []
          }
        ],
        "summary": "complete_upload_session",
        "tags": [
          "files"
        ]
      }
    },
    "/v1/workspaces/{workspace_id}/upload-sessions/{session_id}/parts/{part_number}": {
      "put": {
        "description": "Upload one part of a chunked upload. Cost class: **fast**.\n\nExempt from the tenant's per-minute rate limit (unlike every other\nupload-session route): a multi-GB file at ``chunk_size`` is already\ndozens of requests, and each part is bounded and byte-for-byte\nrevalidated at ``complete`` anyway, so RPM protection would only add\nfriction here without protecting anything.\n\nIdempotent: re-PUTing the same ``part_number`` overwrites it, so a\nretried part after a dropped connection is always safe.",
        "operationId": "upload_session_part_v1_workspaces__workspace_id__upload_sessions__session_id__parts__part_number__put",
        "parameters": [
          {
            "description": "0-based part index.",
            "in": "path",
            "name": "part_number",
            "required": true,
            "schema": {
              "description": "0-based part index.",
              "minimum": 0,
              "title": "Part Number",
              "type": "integer"
            }
          },
          {
            "description": "Workspace identifier.",
            "in": "path",
            "name": "workspace_id",
            "required": true,
            "schema": {
              "description": "Workspace identifier.",
              "format": "uuid",
              "title": "Workspace Id",
              "type": "string"
            }
          },
          {
            "description": "Upload session identifier.",
            "in": "path",
            "name": "session_id",
            "required": true,
            "schema": {
              "description": "Upload session identifier.",
              "format": "uuid",
              "title": "Session Id",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadSessionPartResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "504": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Gateway Timeout"
          },
          "default": {
            "content": {
              "application/json": {
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "detail": null,
                    "message": "Request body has extra fields that this operation does not accept.",
                    "request_id": "req-01j9k2n3p4q5r6s7t8v9",
                    "retryable": false
                  }
                },
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            },
            "description": "Typed error envelope used by every 4xx and 5xx. ``error.code`` distinguishes the failure; HTTP status is a consequence of the code."
          }
        },
        "security": [
          {
            "UploadSessionTokenHeader": []
          }
        ],
        "summary": "upload_session_part",
        "tags": [
          "files"
        ]
      }
    }
  },
  "security": [],
  "servers": [
    {
      "url": "https://ndi-api.nace.ai"
    }
  ],
  "tags": []
}
