{"components":{"responses":{"BadRequest":{"description":"Bad Request"},"Found":{"description":"Found"},"InternalServerError":{"description":"Internal Server Error"},"NotFound":{"description":"Not Found"},"SeeOther":{"description":"See Other"},"Unauthorized":{"description":"Unauthorized"}},"schemas":{"AddResult":{"properties":{"status":{"enum":["added","invited"],"type":"string"}},"required":["status"],"type":"object"},"Atom":{"properties":{"binary":{"items":{"format":"int32","minimum":0,"type":"integer"},"nullable":true,"type":"array"},"file_id":{"description":"Derived — opaque `file-…` id of the joined `files` row (deterministic picker: smallest version, tiebreak by created_at then file_id). UI download/delete links route off this so they keep working when paths repeat across versions.","nullable":true,"type":"string"},"id":{"description":"u64 hashes nearly always exceed 2^53, so the wire format is decimal string; see [`crate::serde_helpers::u64_str_opt`] and issue #68.","nullable":true,"type":"string"},"metadata":{},"related_nodes":{"items":{"type":"string"},"nullable":true,"type":"array"},"score":{"format":"float","nullable":true,"type":"number"},"sequence_index":{"format":"int32","minimum":0,"nullable":true,"type":"integer"},"tags":{"description":"Derived — set on the search read path by joining `content_hash` to the current `files` row's `tags`. Never written; the atoms table has no `tags` column post-D2.","items":{"type":"string"},"nullable":true,"type":"array"},"text":{"type":"string"},"uri":{"description":"Derived — set on the search read path by joining `content_hash` to the current `files` row's `path`. Never written; the atoms table has no `uri` column post-D2.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"}},"required":["text","metadata"],"type":"object"},"AtomObject":{"properties":{"binary":{"items":{"format":"int32","minimum":0,"type":"integer"},"nullable":true,"type":"array"},"file_id":{"description":"Derived — opaque file-… id of the joined files row (deterministic picker: smallest version, tiebreak by created_at then file_id). UI download/delete links route off this so they keep working when paths repeat across versions.","nullable":true,"type":"string"},"id":{"description":"u64 hashes nearly always exceed 2^53, so the wire format is decimal string; see serde_helpers::u64_str_opt and issue #68.","nullable":true,"type":"string"},"metadata":{},"related_nodes":{"items":{"type":"string"},"nullable":true,"type":"array"},"score":{"format":"float","nullable":true,"type":"number"},"sequence_index":{"format":"int32","minimum":0,"nullable":true,"type":"integer"},"tags":{"description":"Derived — set on the search read path by joining content_hash to the current files row's tags. Never written; the atoms table has no tags column post-D2.","items":{"type":"string"},"nullable":true,"type":"array"},"text":{"type":"string"},"uri":{"description":"Derived — set on the search read path by joining content_hash to the current files row's path. Never written; the atoms table has no uri column post-D2.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"}},"required":["text","metadata"],"type":"object"},"AuditEntry":{"properties":{"actor_subject":{"type":"string"},"at":{"format":"date-time","type":"string"},"event":{"type":"string"},"id":{"format":"uuid","type":"string"},"metadata":{"additionalProperties":true,"type":"object"},"user_id":{"format":"uuid","nullable":true,"type":"string"}},"required":["id","at","event","actor_subject"],"type":"object"},"CompleteUploadRequest":{"description":"Request body for `POST /v1/uploads/{upload_id}/complete`.\n`part_ids` is the caller-controlled assembly order: the final file bytes are produced by concatenating parts in the order of this slice, not in upload arrival order.\n`md5` — despite the OpenAI field name — accepts a `blake3:\u003c64 hex chars\u003e` digest that is checked against the assembled bytes before the file row is committed. A mismatch returns HTTP 409.\n","properties":{"md5":{"description":"Optional `blake3:\u003c64 hex chars\u003e` digest of the assembled content. Checked before commit; mismatch → HTTP 409.\n","nullable":true,"type":"string"},"part_ids":{"description":"Ordered list of `part_id` values. Assembly follows this order exactly.","items":{"type":"string"},"type":"array"}},"required":["part_ids"],"type":"object"},"ContractEvent":{"properties":{"actor":{"type":"string"},"createdAt":{"type":"string"},"details":{"type":"string"},"event":{"type":"string"},"ip":{"type":"string"},"userAgent":{"type":"string"}},"required":["event","createdAt"],"type":"object"},"ContractFields":{"properties":{"customer_address":{"maxLength":500,"minLength":2,"type":"string"},"customer_legal_name":{"maxLength":200,"minLength":2,"type":"string"},"customer_rep_email":{"maxLength":320,"minLength":3,"type":"string"},"customer_rep_name":{"maxLength":200,"minLength":2,"type":"string"},"customer_rep_title":{"maxLength":200,"minLength":2,"type":"string"},"effective_date":{"maxLength":10,"minLength":10,"type":"string"},"included_atoms":{"minimum":0,"type":"integer"},"included_searches_per_month":{"minimum":0,"type":"integer"},"included_storage_gb":{"minimum":0,"type":"integer"},"included_vector_stores":{"maximum":100,"minimum":1,"type":"integer"},"monthly_fee":{"minimum":0,"type":"number"},"payment_terms_days":{"maximum":90,"minimum":0,"type":"integer"},"price_protection_months":{"maximum":60,"minimum":0,"type":"integer"},"usage_premium_applied":{"type":"boolean"},"usage_premium_pct":{"maximum":100,"minimum":0,"type":"number"}},"required":["customer_legal_name","customer_address","customer_rep_name","customer_rep_title","customer_rep_email","effective_date"],"type":"object"},"ContractSummary":{"properties":{"createdAt":{"type":"string"},"customerLegalName":{"type":"string"},"id":{"type":"string"},"monthlyFee":{"type":"number"},"status":{"enum":["draft","sent","order_form_accepted","executed","voided"],"type":"string"},"updatedAt":{"type":"string"}},"required":["id","status","customerLegalName","monthlyFee","createdAt","updatedAt"],"type":"object"},"DeletedFile":{"properties":{"deleted":{"type":"boolean"},"id":{"type":"string"},"object":{"type":"string"}},"required":["id","object","deleted"],"type":"object"},"DeletedObject":{"properties":{"deleted":{"type":"boolean"},"id":{"type":"string"},"object":{"type":"string"}},"required":["id","object","deleted"],"type":"object"},"FileObject":{"properties":{"atom_count":{"description":"Number of atoms generated by chunking. 0 until chunking completes.","format":"int64","minimum":0,"type":"integer"},"atoms_vectorized":{"description":"#233: atoms vectorized so far (vs. `atom_count` total) — the per-file vectorization-progress numerator, so a client can render a true `atoms_vectorized / atom_count` fraction while a file processes. Present on list/retrieve/modify of an actual file; omitted on upload/fetch stubs. Counted from the BASE atoms table, so under LSM mode (`KNOWDB_LSM_ATOMS`) it LAGS by the compactor merge + read-handle refresh window — a fully-vectorized file can briefly read `atoms_vectorized \u003c atom_count`; same base-truth semantics as the per-VS `atoms_unvectorized` backlog (#230).","format":"int64","minimum":0,"nullable":true,"type":"integer"},"bytes":{"format":"int64","minimum":0,"type":"integer"},"bytes_fetched":{"description":"Bytes downloaded so far. Equals `bytes` once the worker promotes the fetch into the content table.","format":"int64","minimum":0,"type":"integer"},"bytes_total":{"description":"`Content-Length`-advertised total. Null until known; equals `bytes_fetched` at completion.","format":"int64","minimum":0,"nullable":true,"type":"integer"},"chunk_count":{"format":"int64","minimum":0,"nullable":true,"type":"integer"},"content_hash":{"description":"#277: OCI-style content digest `blake3:\u003chex\u003e` of the source bytes — the same value used as the `GET /v1/files/{id}/content` ETag and surfaced on `FileEvent.content_hash` / `capabilities.digests`. Present on an actual file (retrieve/list/modify/wait); null on fetch-job / streaming-upload stubs that have no content row yet. Consumers SHOULD treat the algorithm prefix as opaque.","nullable":true,"type":"string"},"created_at":{"format":"int64","minimum":0,"type":"integer"},"created_by":{"description":"#374: the actor who created THIS file version, in the canonical `Claims::to_actor_string()` form — `bearer:\u003csub\u003e`, `oauth2:\u003csub\u003e`, `oidc:\u003csub\u003e`, `apikey:\u003cpaserk-id\u003e`, or a `system:*` form. Version- scoped (keyed `(vector_store_id, path, version)`), so re-uploading a path mints a new row with a new `created_by`. `None` only on stubs with no resolvable file row (fetch jobs, streaming-upload placeholders).","nullable":true,"type":"string"},"etag":{"description":"#389/#390: opaque CAS token derived from the current row's mutable state (path/tags/updated_at/superseded_at/version). Pass back as `if_match` on `PATCH /v1/vector_stores/{vs}/files` (or MCP `mutate_files`) to make the mutation conditional on nothing else having changed the row since this read. `None` on stubs with no resolvable file row.","nullable":true,"type":"string"},"filename":{"type":"string"},"id":{"type":"string"},"last_modified_at":{"description":"#238: the current version's upload time (`MAX(version.created_at)`).","format":"int64","minimum":0,"type":"integer"},"mime_type":{"nullable":true,"type":"string"},"object":{"type":"string"},"phase":{"description":"Raw internal `content.status` value (`pending`/`text_extracted`/`chunked`/`completed`/`error`/ `quarantined`/`fetching`). Surfaces the granular pipeline phase for callers who want to distinguish stages within `processing` or detect `quarantined` behind the coarse `error` bucket. Issue #36.","nullable":true,"type":"string"},"prior_version_id":{"description":"`file_id` of the immediately-prior version for this `(vector_store_id, path)`, if any. Populated on list / retrieve / revert responses so a caller wanting \"roll head back one step\" can `POST /v1/files/{prior_version_id}/revert` without first fetching the chain. `None` when this row has no predecessor or when the field was not populated by this code path (uploads).","nullable":true,"type":"string"},"purpose":{"type":"string"},"status":{"description":"OpenAI File status: `uploaded` / `processing` / `processed` / `error`. Mapped from the internal `content.status` via [`crate::status::internal_to_openai_file_status`]. The terminal internal states `error`, `retained` (tombstoned) and `quarantined` (parked by the stale-pending sweep) all collapse into `error`; read `phase` to tell them apart.","type":"string"},"status_details":{"description":"Free-form error description when `status == \"error\"`.","nullable":true,"type":"string"},"superseded_by":{"description":"#374: the actor who superseded this version, set on the OLD row when a new version takes over. Pairs with `superseded_at`, so it is **always null on a current version** — non-null only on a historical row (e.g. via `prior_version_id`). Same canonical actor form.","nullable":true,"type":"string"},"tags":{"items":{"type":"string"},"nullable":true,"type":"array"},"updated_at":{"description":"#238: the current version's last status/state transition time (`content.coalesce(updated_at, created_at)`).","format":"int64","minimum":0,"type":"integer"},"updated_by":{"description":"#374: the actor of the last IN-PLACE mutation of this row (e.g. a #232/#17 tag change). Bumped on real mutations, preserved on no-ops, so it equals `created_by` for a file nobody has modified since upload. Pairs with `last_modified_at`. Same canonical actor form as `created_by`.","nullable":true,"type":"string"},"url":{"description":"The source URL, when the file was created via URL ingest.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"},"vector_store_name":{"description":"#328: the vector store's mutable human label (its `name`), populated alongside `vector_store_id` on file read paths; `null` on stubs with no resolvable store.","nullable":true,"type":"string"},"version_count":{"description":"Total number of file rows for this `(vector_store_id, path)`, including the current row and every superseded row still kept by retention. The UI uses `version_count \u003e 1` to decide whether to surface a \"revert\" action. Always populated on list / retrieve responses; left `None` on the directory-stub upload path.","format":"int32","minimum":0,"nullable":true,"type":"integer"}},"required":["id","bytes","created_at","filename","object","purpose","status","bytes_fetched","atom_count","last_modified_at","updated_at"],"type":"object"},"FileObject:conflict:43WD":{"properties":{"atom_count":{"description":"Number of atoms generated by chunking. 0 until chunking completes.","format":"int64","minimum":0,"type":"integer"},"atoms_vectorized":{"description":"#233: atoms vectorized so far (vs. `atom_count` total) — the per-file vectorization-progress numerator. Present on list/retrieve/modify of an actual file; omitted on upload/fetch stubs. Counted from the BASE atoms table, so under LSM mode (`KNOWDB_LSM_ATOMS`) it LAGS by the compactor merge + read-handle refresh window; same base-truth semantics as the per-VS `atoms_unvectorized` backlog (#230).","format":"int64","minimum":0,"nullable":true,"type":"integer"},"bytes":{"format":"int64","minimum":0,"type":"integer"},"bytes_fetched":{"description":"Bytes downloaded so far. Equals `bytes` once the worker promotes the fetch into the content table.","format":"int64","minimum":0,"type":"integer"},"bytes_total":{"description":"`Content-Length`-advertised total. Null until known; equals `bytes_fetched` at completion.","format":"int64","minimum":0,"nullable":true,"type":"integer"},"chunk_count":{"format":"int64","minimum":0,"nullable":true,"type":"integer"},"content_hash":{"description":"#277: OCI-style content digest `blake3:\u003chex\u003e` of the source bytes — same value as the `GET /v1/files/{id}/content` ETag. Present on an actual file; null on fetch-job / streaming-upload stubs with no content row yet. Treat the algorithm prefix as opaque.","nullable":true,"type":"string"},"created_at":{"format":"int64","minimum":0,"type":"integer"},"created_by":{"description":"#374: actor who created THIS file version (canonical `Claims::to_actor_string()` form). Version-scoped; `None` only on stubs with no resolvable file row.","nullable":true,"type":"string"},"etag":{"description":"#389/#390: opaque CAS token for `PATCH /v1/vector_stores/{vs}/files` `if_match`. `None` on stubs with no resolvable file row.","nullable":true,"type":"string"},"filename":{"type":"string"},"id":{"type":"string"},"last_modified_at":{"description":"#238: the current version's upload time (`MAX(version.created_at)`).","format":"int64","minimum":0,"type":"integer"},"mime_type":{"nullable":true,"type":"string"},"object":{"type":"string"},"phase":{"description":"Raw internal `content.status` value (`pending`/`text_extracted`/`chunked`/`completed`/`error`/ `quarantined`/`fetching`). Surfaces the granular pipeline phase. Issue #36.","nullable":true,"type":"string"},"prior_version_id":{"description":"`file_id` of the immediately-prior version for this `(vector_store_id, path)`, if any.","nullable":true,"type":"string"},"purpose":{"type":"string"},"status":{"description":"OpenAI File status: `uploaded` / `processing` / `processed` / `error`. Mapped from the internal `content.status`. The terminal internal states `error`, `retained` (tombstoned) and `quarantined` all collapse into `error`; read `phase` to tell them apart.","type":"string"},"status_details":{"description":"Free-form error description when `status == \"error\"`.","nullable":true,"type":"string"},"superseded_by":{"description":"#374: actor who superseded this version (set on the OLD row); always null on a current version.","nullable":true,"type":"string"},"tags":{"items":{"type":"string"},"nullable":true,"type":"array"},"updated_at":{"description":"#238: the current version's last status/state transition time (`content.coalesce(updated_at, created_at)`).","format":"int64","minimum":0,"type":"integer"},"updated_by":{"description":"#374: actor of the last in-place mutation; equals `created_by` for a file unmodified since upload. Pairs with `last_modified_at`.","nullable":true,"type":"string"},"url":{"description":"The source URL, when the file was created via URL ingest.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"},"vector_store_name":{"description":"#328: the vector store's mutable human label (its `name`), populated alongside `vector_store_id` on file read paths; `null` on stubs with no resolvable store.","nullable":true,"type":"string"},"version_count":{"description":"Total number of file rows for this `(vector_store_id, path)`, including the current row and every superseded row kept by retention.","format":"int32","minimum":0,"nullable":true,"type":"integer"}},"required":["id","bytes","created_at","filename","object","purpose","status","bytes_fetched","atom_count","last_modified_at","updated_at"],"type":"object"},"FileObject:conflict:P7N2":{"description":"knowdb File row embedded in an Upload response.","properties":{"atom_count":{"description":"Number of atoms generated by chunking. 0 until chunking completes.","format":"int64","minimum":0,"type":"integer"},"atoms_vectorized":{"description":"#233: atoms vectorized so far (vs. `atom_count` total) — the per-file vectorization-progress numerator. Present on list/retrieve/modify of an actual file; omitted on upload/fetch stubs. Counted from the BASE atoms table, so under LSM mode (`KNOWDB_LSM_ATOMS`) it LAGS by the compactor merge + read-handle refresh window — a fully-vectorized file can briefly read `atoms_vectorized \u003c atom_count`; same base-truth semantics as the per-VS `atoms_unvectorized` backlog (#230).","format":"int64","minimum":0,"nullable":true,"type":"integer"},"bytes":{"format":"int64","minimum":0,"type":"integer"},"bytes_fetched":{"description":"Bytes downloaded so far. Equals `bytes` once the worker promotes the fetch into the content table.\n","format":"int64","minimum":0,"type":"integer"},"bytes_total":{"description":"`Content-Length`-advertised total. Null until known; equals `bytes_fetched` at completion.\n","format":"int64","minimum":0,"nullable":true,"type":"integer"},"chunk_count":{"format":"int64","minimum":0,"nullable":true,"type":"integer"},"content_hash":{"description":"#277: OCI-style content digest `blake3:\u003chex\u003e` of the source bytes — same value as the `GET /v1/files/{id}/content` ETag. Present on an actual file; null on fetch-job / streaming-upload stubs with no content row yet. Treat the algorithm prefix as opaque.","nullable":true,"type":"string"},"created_at":{"format":"int64","minimum":0,"type":"integer"},"created_by":{"description":"#374: actor who created THIS file version (canonical `Claims::to_actor_string()` form). Version-scoped; `None` only on stubs with no resolvable file row.","nullable":true,"type":"string"},"etag":{"description":"#389/#390: opaque CAS token for `PATCH /v1/vector_stores/{vs}/files` `if_match`. `None` on stubs with no resolvable file row.","nullable":true,"type":"string"},"filename":{"type":"string"},"id":{"type":"string"},"last_modified_at":{"description":"#238: the current version's upload time (`MAX(version.created_at)`).","format":"int64","minimum":0,"type":"integer"},"mime_type":{"nullable":true,"type":"string"},"object":{"type":"string"},"phase":{"description":"Raw internal `content.status` value (`pending`/`text_extracted`/`chunked`/`completed`/`error`/ `quarantined`/`fetching`). Surfaces the granular pipeline phase for callers who want to distinguish stages within `processing` or detect `quarantined` behind the coarse `error` bucket. Issue #36.\n","nullable":true,"type":"string"},"prior_version_id":{"description":"`file_id` of the immediately-prior version for this `(vector_store_id, path)`, if any. Populated on list / retrieve / revert responses so a caller wanting \"roll head back one step\" can `POST /v1/files/{prior_version_id}/revert` without first fetching the chain. `None` when this row has no predecessor or when the field was not populated by this code path (uploads).\n","nullable":true,"type":"string"},"purpose":{"type":"string"},"status":{"description":"OpenAI File status: `uploaded` / `processing` / `processed` / `error`. Mapped from the internal `content.status` via [`crate::status::internal_to_openai_file_status`]. The terminal internal states `error`, `retained` (tombstoned) and `quarantined` (parked by the stale-pending sweep) all collapse into `error`; read `phase` to tell them apart.\n","type":"string"},"status_details":{"description":"Free-form error description when `status == \"error\"`.","nullable":true,"type":"string"},"superseded_by":{"description":"#374: actor who superseded this version (set on the OLD row); always null on a current version.","nullable":true,"type":"string"},"tags":{"items":{"type":"string"},"nullable":true,"type":"array"},"updated_at":{"description":"#238: the current version's last status/state transition time (`content.coalesce(updated_at, created_at)`).","format":"int64","minimum":0,"type":"integer"},"updated_by":{"description":"#374: actor of the last in-place mutation; equals `created_by` for a file unmodified since upload. Pairs with `last_modified_at`.","nullable":true,"type":"string"},"url":{"description":"The source URL, when the file was created via URL ingest.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"},"vector_store_name":{"description":"#328: the vector store's mutable human label (its `name`), populated alongside `vector_store_id` on file read paths; `null` on stubs with no resolvable store.","nullable":true,"type":"string"},"version_count":{"description":"Total number of file rows for this `(vector_store_id, path)`, including the current row and every superseded row still kept by retention. The UI uses `version_count \u003e 1` to decide whether to surface a \"revert\" action. Always populated on list / retrieve responses; left `None` on the directory-stub upload path.\n","format":"int32","minimum":0,"nullable":true,"type":"integer"}},"required":["id","bytes","created_at","filename","object","purpose","status","bytes_fetched","atom_count","last_modified_at","updated_at"],"type":"object"},"InitiateUploadRequest":{"description":"Request body for `POST /v1/uploads` — opens a new ranged-write upload session.","properties":{"bytes":{"format":"int64","minimum":0,"type":"integer"},"expected_content_hash":{"description":"Optional: `blake3:\u003c64 hex chars\u003e` whole-file digest checked at complete time. knowdb extension.\n","nullable":true,"type":"string"},"filename":{"type":"string"},"mime_type":{"type":"string"},"purpose":{"type":"string"},"tags":{"description":"Optional free-form tags applied to the resulting file row. knowdb extension.","items":{"type":"string"},"nullable":true,"type":"array"},"vector_store_id":{"description":"Optional scope the resulting file to a specific vector store. knowdb extension.","nullable":true,"type":"string"}},"required":["filename","bytes","mime_type","purpose"],"type":"object"},"Invitation":{"properties":{"created_at":{"format":"date-time","nullable":true,"type":"string"},"email":{"type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"invited_by":{"nullable":true,"type":"string"},"role":{"type":"string"}},"required":["id","email","role","expires_at"],"type":"object"},"JsonRpcRequest":{"properties":{"id":{},"jsonrpc":{"type":"string"},"method":{"type":"string"},"params":{}},"required":["jsonrpc","method"],"type":"object"},"JsonRpcResponse":{"properties":{"error":{"nullable":true,"properties":{"code":{"format":"int32","type":"integer"},"data":{},"message":{"type":"string"}},"required":["code","message"],"type":"object"},"id":{},"jsonrpc":{"type":"string"},"result":{}},"required":["jsonrpc","id"],"type":"object"},"ListAtomsResponse":{"description":"One page of a single file's atoms. Mirrors `ListFilesResponse`.","properties":{"data":{"items":{"$ref":"#/components/schemas/Atom"},"type":"array"},"has_more":{"type":"boolean"},"next_after":{"nullable":true,"type":"string"},"object":{"type":"string"}},"required":["object","data","has_more"],"type":"object"},"ListFilesResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/FileObject"},"type":"array"},"has_more":{"type":"boolean"},"next_after":{"nullable":true,"type":"string"},"object":{"type":"string"}},"required":["object","data","has_more"],"type":"object"},"Member":{"properties":{"display_name":{"nullable":true,"type":"string"},"email":{"type":"string"},"family_name":{"nullable":true,"type":"string"},"given_name":{"nullable":true,"type":"string"},"last_login_at":{"format":"date-time","nullable":true,"type":"string"},"role":{"type":"string"},"user_id":{"format":"uuid","type":"string"}},"required":["user_id","email","role"],"type":"object"},"MyInvitation":{"properties":{"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"invited_by":{"nullable":true,"type":"string"},"role":{"type":"string"},"store_id":{"type":"string"},"store_name":{"nullable":true,"type":"string"}},"required":["id","store_id","role","expires_at"],"type":"object"},"PasswordResetMint":{"properties":{"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"token":{"type":"string"}},"required":["id","token","expires_at"],"type":"object"},"RenameResult":{"properties":{"display_name":{"type":"string"},"id":{"type":"string"}},"required":["id","display_name"],"type":"object"},"ReprocessResponse":{"description":"Response body for `POST /v1/files/{file_id}/reprocess`.","properties":{"atoms_cleared":{"description":"Number of atoms deleted. May be 0 when called on a still-pending file.","format":"int64","minimum":0,"type":"integer"},"file_id":{"description":"The file_id that was reprocessed.","type":"string"},"status":{"description":"Content status after the reset. Always `\"pending\"` on success.","type":"string"},"vector_store_id":{"description":"Vector store the file belongs to (`None` = system/unscoped store).","nullable":true,"type":"string"}},"required":["file_id","atoms_cleared","status"],"type":"object"},"SearchAtom":{"properties":{"binary":{"items":{"format":"int32","minimum":0,"type":"integer"},"nullable":true,"type":"array"},"file_id":{"description":"Derived — opaque `file-…` id of the joined `files` row (deterministic picker: smallest version, tiebreak by created_at then file_id). UI download/delete links route off this so they keep working when paths repeat across versions.","nullable":true,"type":"string"},"id":{"description":"u64 hashes nearly always exceed 2^53, so the wire format is decimal string; see [`crate::serde_helpers::u64_str_opt`] and issue #68.","nullable":true,"type":"string"},"metadata":{},"related_nodes":{"items":{"type":"string"},"nullable":true,"type":"array"},"score":{"format":"float","nullable":true,"type":"number"},"sequence_index":{"format":"int32","minimum":0,"nullable":true,"type":"integer"},"tags":{"description":"Derived — set on the search read path by joining `content_hash` to the current `files` row's `tags`. Never written; the atoms table has no `tags` column post-D2.","items":{"type":"string"},"nullable":true,"type":"array"},"text":{"type":"string"},"uri":{"description":"Derived — set on the search read path by joining `content_hash` to the current `files` row's `path`. Never written; the atoms table has no `uri` column post-D2.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"}},"required":["text","metadata"],"type":"object"},"SearchField":{"description":"Vector field a `vector`/`hybrid` query is matched against.","enum":["text","vision","audio"],"nullable":true,"type":"string"},"SearchMode":{"description":"Search mode for `/v1/search`. Mirrors the MCP `search_atoms` enum so generated SDKs advertise the same valid set the handler validates.","enum":["hybrid","vector","fts"],"nullable":true,"type":"string"},"SearchResponse":{"properties":{"atoms":{"items":{"$ref":"#/components/schemas/SearchAtom"},"type":"array"},"processing_time_ms":{"format":"int64","minimum":0,"type":"integer"},"status":{"type":"string"},"total_count":{"minimum":0,"nullable":true,"type":"integer"}},"required":["status","atoms","processing_time_ms"],"type":"object"},"Store":{"properties":{"display_name":{"nullable":true,"type":"string"},"id":{"type":"string"},"included_atoms":{"format":"int64","type":"integer"},"included_bytes":{"format":"int64","type":"integer"},"owner":{"type":"boolean"},"plan":{"enum":["free","launch","scale","enterprise"],"type":"string"},"quota_bytes":{"format":"int64","type":"integer"},"role":{"type":"string"}},"required":["id","role","owner","quota_bytes","plan","included_bytes","included_atoms"],"type":"object"},"UploadObject":{"description":"OpenAI-compatible Upload object returned by `/v1/uploads`.","properties":{"bytes":{"format":"int64","minimum":0,"type":"integer"},"created_at":{"format":"int64","type":"integer"},"expires_at":{"format":"int64","type":"integer"},"file":{"$ref":"#/components/schemas/FileObject"},"filename":{"type":"string"},"id":{"type":"string"},"object":{"type":"string"},"purpose":{"type":"string"},"status":{"type":"string"}},"required":["id","object","bytes","created_at","filename","purpose","status","expires_at"],"type":"object"},"UploadPartObject":{"description":"OpenAI-compatible UploadPart object returned by `POST /v1/uploads/{upload_id}/parts`.\nRepresents one successfully committed chunk within an in-progress upload session. The `id` field uses the `part_\u003c24\u003e` prefix scheme; `upload_id` echoes the parent session so callers can correlate parts without extra state.\n","properties":{"created_at":{"description":"Unix timestamp (seconds) when this part was stored.","format":"int64","type":"integer"},"id":{"description":"Opaque part identifier — `part_\u003c24 alphanum chars\u003e`.","type":"string"},"object":{"description":"Always `\"upload.part\"`.","type":"string"},"upload_id":{"description":"The `upload_id` of the parent session.","type":"string"}},"required":["id","object","upload_id","created_at"],"type":"object"},"User":{"properties":{"avatar_url":{"nullable":true,"type":"string"},"created_at":{"format":"date-time","type":"string"},"display_name":{"nullable":true,"type":"string"},"email":{"format":"email","type":"string"},"email_verified_at":{"format":"date-time","nullable":true,"type":"string"},"family_name":{"nullable":true,"type":"string"},"given_name":{"nullable":true,"type":"string"},"id":{"format":"uuid","type":"string"},"last_login_at":{"format":"date-time","nullable":true,"type":"string"},"mfa_required":{"type":"boolean"},"preferred_language":{"type":"string"},"purged_at":{"format":"date-time","nullable":true,"type":"string"},"status":{"enum":["invited","active","disabled","deleted"],"type":"string"},"timezone":{"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"required":["id","email","status","preferred_language","timezone","mfa_required","created_at","updated_at"],"type":"object"},"VSInfo":{"properties":{"id":{"nullable":true,"type":"string"},"knowdb_synced":{"type":"boolean"},"quota_atoms":{"format":"int64","nullable":true,"type":"integer"},"quota_bytes":{"format":"int64","nullable":true,"type":"integer"},"status":{"enum":["provisioned","exists","updated","none"],"type":"string"}},"required":["status"],"type":"object"},"VectorStoreFileObject":{"properties":{"atom_count":{"description":"Number of atoms generated by chunking. 0 until chunking completes.","format":"int64","minimum":0,"type":"integer"},"atoms_vectorized":{"description":"#233: atoms vectorized so far (vs. `atom_count` total) — the per-file vectorization-progress numerator. Present on list/retrieve/modify of an actual file; omitted on upload/fetch stubs. Counted from the BASE atoms table, so under LSM mode (`KNOWDB_LSM_ATOMS`) it LAGS by the compactor merge + read-handle refresh window; same base-truth semantics as the per-VS `atoms_unvectorized` backlog (#230).","format":"int64","minimum":0,"nullable":true,"type":"integer"},"bytes":{"format":"int64","minimum":0,"type":"integer"},"bytes_fetched":{"description":"Bytes downloaded so far. Equals `bytes` once the worker promotes the fetch into the content table.","format":"int64","minimum":0,"type":"integer"},"bytes_total":{"description":"Content-Length-advertised total. Null until known; equals `bytes_fetched` at completion.","format":"int64","minimum":0,"nullable":true,"type":"integer"},"chunk_count":{"format":"int64","minimum":0,"nullable":true,"type":"integer"},"content_hash":{"description":"#277: OCI-style content digest `blake3:\u003chex\u003e` of the source bytes — same value as the `GET /v1/files/{id}/content` ETag. Present on an actual file; null on fetch-job / streaming-upload stubs with no content row yet. Treat the algorithm prefix as opaque.","nullable":true,"type":"string"},"created_at":{"format":"int64","minimum":0,"type":"integer"},"created_by":{"description":"#374: actor who created THIS file version, canonical `Claims::to_actor_string()` form (`bearer:\u003csub\u003e`/`oauth2:\u003csub\u003e`/ `oidc:\u003csub\u003e`/`apikey:\u003cpaserk-id\u003e`/`system:*`). Version-scoped. `None` only on stubs with no resolvable file row.","nullable":true,"type":"string"},"etag":{"description":"#389/#390: opaque CAS token derived from the row's mutable state. Pass back as `if_match` on `PATCH /v1/vector_stores/{vs}/files` (or MCP `mutate_files`) to make the mutation conditional. `None` on stubs with no resolvable file row.","nullable":true,"type":"string"},"filename":{"type":"string"},"id":{"type":"string"},"last_modified_at":{"description":"#238: the current version's upload time (`MAX(version.created_at)`).","format":"int64","minimum":0,"type":"integer"},"mime_type":{"nullable":true,"type":"string"},"object":{"type":"string"},"phase":{"description":"Raw internal content.status value (pending/text_extracted/chunked/completed/error/quarantined/fetching). Surfaces the granular pipeline phase for callers who want to distinguish stages within `processing` or detect `quarantined` behind the coarse `error` bucket. Issue #36.","nullable":true,"type":"string"},"prior_version_id":{"description":"file_id of the immediately-prior version for this (vector_store_id, path), if any. Populated on list / retrieve / revert responses so a caller wanting \"roll head back one step\" can POST /v1/files/{prior_version_id}/revert without first fetching the chain. None when this row has no predecessor or when the field was not populated by this code path (uploads).","nullable":true,"type":"string"},"purpose":{"type":"string"},"status":{"description":"OpenAI File status: `uploaded` / `processing` / `processed` / `error`. Mapped from the internal content.status. The terminal internal states `error`, `retained` (tombstoned) and `quarantined` (parked by the stale-pending sweep) all collapse into `error`; read `phase` to tell them apart.","type":"string"},"status_details":{"description":"Free-form error description when `status == \"error\"`.","nullable":true,"type":"string"},"superseded_by":{"description":"#374: actor who superseded this version (set on the OLD row). Always null on a current version; non-null only on a historical row. Same canonical actor form.","nullable":true,"type":"string"},"tags":{"items":{"type":"string"},"nullable":true,"type":"array"},"updated_at":{"description":"#238: the current version's last status/state transition time (`content.coalesce(updated_at, created_at)`).","format":"int64","minimum":0,"type":"integer"},"updated_by":{"description":"#374: actor of the last in-place mutation of this row; equals `created_by` for a file unmodified since upload. Pairs with `last_modified_at`. Same canonical actor form.","nullable":true,"type":"string"},"url":{"description":"The source URL, when the file was created via URL ingest.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"},"vector_store_name":{"description":"#328: the vector store's mutable human label (its `name`), populated alongside `vector_store_id` on file read paths; `null` on stubs with no resolvable store.","nullable":true,"type":"string"},"version_count":{"description":"Total number of file rows for this (vector_store_id, path), including the current row and every superseded row still kept by retention. The UI uses version_count \u003e 1 to decide whether to surface a \"revert\" action.","format":"int32","minimum":0,"nullable":true,"type":"integer"}},"required":["id","bytes","created_at","filename","object","purpose","status","bytes_fetched","atom_count","last_modified_at","updated_at"],"type":"object"},"VectorStoreObject":{"properties":{"atom_count":{"format":"int64","minimum":0,"type":"integer"},"atoms_unvectorized":{"description":"#230: materialized atom-level vectorization backlog for this VS — count of atoms whose vectors are all NULL. Incremented +N when chunking writes a content's atoms, decremented −N when the worker vectorizes them. Summed across VS rows for the global `queue.atoms_unvectorized`, replacing the full atoms-table scan on the read path; the maintenance singleton runs a periodic reconciliation scan to heal delta drift.","format":"int64","minimum":0,"type":"integer"},"capabilities":{"description":"Per-VS feature toggles + quotas (issue #8). Distinct from the server-wide Capabilities advertised at /v1/capabilities. Every knob is Option\u003cT\u003e — None means \"fall through to the global default\" (operator-set env var). Serialised as a JSON string in the capabilities Utf8 column on the vector_stores table.","nullable":true,"properties":{"audio_embeddings_enabled":{"description":"Override the global KNOWDB_ENABLE_AUDIO_EMBEDDINGS for atoms ingested into this store. None falls through.","nullable":true,"type":"boolean"},"chunk_overrides":{"description":"Per-VS chunk-size overrides (#70). Each axis falls through to the global KNOWDB_MIN_CHUNK_SIZE / KNOWDB_MAX_CHUNK_SIZE / KNOWDB_CHUNK_OVERLAP_PERCENT when unset.","nullable":true,"properties":{"max_chunk_size":{"minimum":0,"nullable":true,"type":"integer"},"min_chunk_size":{"minimum":0,"nullable":true,"type":"integer"},"overlap_percent":{"minimum":0,"nullable":true,"type":"integer"}},"type":"object"},"ocr_enabled":{"description":"Override the global KNOWDB_ENABLE_OCR for image content uploaded to this store. None falls through to the global.","nullable":true,"type":"boolean"},"quota":{"nullable":true,"properties":{"max_atoms":{"description":"#396: maximum current-version atoms across all files in this store. Composes with the global KNOWDB_MAX_VS_ATOMS via min() — both apply. None / 0 = unlimited per-VS. Enforced as a next-ingest pre-check (atom counts are produced downstream, so an over-cap store rejects the next content upsert).","format":"int64","minimum":0,"nullable":true,"type":"integer"},"max_bytes":{"description":"Maximum total bytes across all content rows in this store. Composes with the global KNOWDB_MAX_VS_BYTES via min() — both apply. None / 0 on this axis = unlimited per-VS; the global ceiling still applies if set.","format":"int64","minimum":0,"nullable":true,"type":"integer"}},"type":"object"},"vision_embeddings_enabled":{"description":"Override the global KNOWDB_ENABLE_VISION_EMBEDDINGS for atoms ingested into this store. None falls through.","nullable":true,"type":"boolean"}},"type":"object"},"created_at":{"format":"int64","type":"integer"},"created_by":{"type":"string"},"etag":{"description":"#379: derived CAS token over this store's mutable state. Pass back as `If-Match` on `POST /v1/vector_stores/{vector_store_id}` to make the capabilities/name merge conditional; a mismatch is refused with 412 rather than silently clobbering a concurrent write. Always populated on read paths; nullable only so it can be omitted from a deserialized request body.","nullable":true,"type":"string"},"file_count":{"format":"int64","minimum":0,"type":"integer"},"file_count_all_versions":{"format":"int64","minimum":0,"type":"integer"},"files_chunked":{"format":"int64","minimum":0,"type":"integer"},"files_completed":{"format":"int64","minimum":0,"type":"integer"},"files_error":{"format":"int64","minimum":0,"type":"integer"},"files_pending":{"description":"#231: per-state counts of **current-version file rows** (`superseded_at IS NULL`), bucketed by the pipeline status of each file's content. Unlike the content-deduped `status_*`, these reconcile with the file total: `files_pending + … + files_quarantined == file_count` for files whose content row is resolvable. A current file whose content row is not yet present (streaming-upload orphan window) or is tombstoned is left unbucketed, so the sum can transiently trail `file_count` by that residual.","format":"int64","minimum":0,"type":"integer"},"files_quarantined":{"format":"int64","minimum":0,"type":"integer"},"files_text_extracted":{"format":"int64","minimum":0,"type":"integer"},"id":{"type":"string"},"last_modified_at":{"format":"int64","minimum":0,"nullable":true,"type":"integer"},"name":{"type":"string"},"object":{"type":"string"},"requirements":{"items":{"type":"string"},"nullable":true,"type":"array"},"status_chunked":{"format":"int64","minimum":0,"type":"integer"},"status_completed":{"format":"int64","minimum":0,"type":"integer"},"status_error":{"format":"int64","minimum":0,"type":"integer"},"status_fetching":{"description":"#231: in-flight URL-ingest fetch jobs for this VS (`STATUS_FETCHING`, counted from `fetch_jobs`). These are files-to-be: no content/file row exists yet, which is why they are surfaced here rather than in `files_*`.","format":"int64","minimum":0,"type":"integer"},"status_pending":{"format":"int64","minimum":0,"type":"integer"},"status_quarantined":{"format":"int64","minimum":0,"type":"integer"},"status_text_extracted":{"format":"int64","minimum":0,"type":"integer"},"total_bytes":{"format":"int64","minimum":0,"type":"integer"},"updated_at":{"format":"int64","type":"integer"},"updated_by":{"type":"string"}},"required":["id","object","created_at","name","file_count","file_count_all_versions","atom_count","total_bytes","status_pending","status_text_extracted","status_chunked","status_completed","status_error","status_quarantined","status_fetching","atoms_unvectorized","files_pending","files_text_extracted","files_chunked","files_completed","files_error","files_quarantined","created_by","updated_at","updated_by"],"type":"object"},"VectorStoreRetrieveFileObject":{"properties":{"bytes":{"description":"File size in bytes. `0` when the content row hasn't materialised yet (e.g. during URL-ingest fetch). Issue","format":"int64","minimum":0,"type":"integer"},"chunk_count":{"format":"int64","minimum":0,"nullable":true,"type":"integer"},"created_at":{"format":"int64","type":"integer"},"etag":{"description":"#389: derived CAS token for `PATCH /v1/vector_stores/{vs}/files` `if_match` — parity with the file object's `etag` and MCP `get_file`. `None` only when no resolvable file row exists.","nullable":true,"type":"string"},"id":{"type":"string"},"object":{"type":"string"},"phase":{"description":"Raw internal content.status value (pending/text_extracted/chunked/completed/error/quarantined/fetching). Surfaces the granular pipeline phase for callers who want to distinguish stages within `in_progress` or detect `quarantined` behind the coarse `failed` bucket. Issue #36.","nullable":true,"type":"string"},"status":{"description":"OpenAI VectorStoreFile status: `in_progress` / `completed` / `failed` / `cancelled`. Mapped from the internal content.status. The terminal internal states `error`, `retained` (tombstoned) and `quarantined` (parked by the stale-pending sweep) all collapse into `failed`; read `phase` to tell them apart.","type":"string"},"vector_store_id":{"type":"string"}},"required":["id","object","created_at","vector_store_id","bytes","status"],"type":"object"},"VectorStoreStats":{"properties":{"category":{"nullable":true,"properties":{"Audio":{"format":"int64","minimum":0,"type":"integer"},"Code":{"format":"int64","minimum":0,"type":"integer"},"Columnar":{"format":"int64","minimum":0,"type":"integer"},"Email":{"format":"int64","minimum":0,"type":"integer"},"Image":{"format":"int64","minimum":0,"type":"integer"},"Notebook":{"format":"int64","minimum":0,"type":"integer"},"Skills":{"format":"int64","minimum":0,"type":"integer"},"Spreadsheet":{"format":"int64","minimum":0,"type":"integer"},"Tabular":{"format":"int64","minimum":0,"type":"integer"},"Text":{"format":"int64","minimum":0,"type":"integer"},"Tools":{"format":"int64","minimum":0,"type":"integer"},"Unknown":{"format":"int64","minimum":0,"type":"integer"},"Video":{"format":"int64","minimum":0,"type":"integer"}},"required":["Tabular","Text","Image","Audio","Video","Code","Tools","Notebook","Skills","Email","Spreadsheet","Columnar","Unknown"],"type":"object"},"mime_top":{"description":"Top-N MIME-type counts. null under fast:true (skipped scan).","items":{"properties":{"count":{"format":"int64","minimum":0,"type":"integer"},"mime":{"type":"string"}},"required":["mime","count"],"type":"object"},"nullable":true,"type":"array"},"name":{"description":"#311: the store's mutable human name. Present alongside vector_store_id on per-store entries (both id and name are returned); null on the fleet aggregate and the fast/empty paths that don't resolve a row.","nullable":true,"type":"string"},"next_after":{"description":"Pagination cursor for fleet roll-up responses. Only present on fleet responses (per_store is Some). Some(name) indicates more stores exist past this page; None means this is the final page.","nullable":true,"type":"string"},"per_store":{"items":{"description":"VectorStoreStats (recursive; elided)","type":"object"},"nullable":true,"type":"array"},"status":{"properties":{"chunked":{"format":"int64","minimum":0,"type":"integer"},"completed":{"format":"int64","minimum":0,"type":"integer"},"error":{"format":"int64","minimum":0,"type":"integer"},"fetching":{"format":"int64","minimum":0,"type":"integer"},"pending":{"format":"int64","minimum":0,"type":"integer"},"quarantined":{"format":"int64","minimum":0,"type":"integer"},"text_extracted":{"format":"int64","minimum":0,"type":"integer"}},"required":["pending","text_extracted","chunked","completed","error","quarantined","fetching"],"type":"object"},"tags_top":{"description":"Top-N tag counts. null under fast:true (skipped scan).","items":{"properties":{"count":{"format":"int64","minimum":0,"type":"integer"},"tag":{"type":"string"}},"required":["tag","count"],"type":"object"},"nullable":true,"type":"array"},"time_range":{"nullable":true,"properties":{"newest_created_at":{"nullable":true,"type":"string"},"oldest_created_at":{"nullable":true,"type":"string"}},"type":"object"},"totals":{"properties":{"atoms":{"format":"int64","minimum":0,"type":"integer"},"bytes":{"format":"int64","minimum":0,"type":"integer"},"files":{"format":"int64","minimum":0,"type":"integer"},"files_all_versions":{"format":"int64","minimum":0,"type":"integer"}},"required":["files","files_all_versions","atoms","bytes"],"type":"object"},"vector_store_id":{"nullable":true,"type":"string"}},"required":["totals","status"],"type":"object"}},"securitySchemes":{"apiKeyCookie":{"description":"Stateless API Token in 'X-API-TOKEN' cookie","in":"cookie","name":"X-API-TOKEN","type":"apiKey"},"apiKeyHeader":{"description":"Stateless API Token in 'X-API-TOKEN' header","in":"header","name":"X-API-TOKEN","type":"apiKey"},"apiKeyQuery":{"description":"Stateless API Token in 'api_token' query parameter","in":"query","name":"api_token","type":"apiKey"},"bearer":{"bearerFormat":"JWT","description":"Bearer Token - This is the default scheme","scheme":"bearer","type":"http"},"oauth2":{"description":"OAuth2 authentication using Password, Authorization Code, or Client Credentials Flow","flows":{"authorizationCode":{"authorizationUrl":"/-/oauth/authorize","scopes":{"openid":"standard oidc scope","profile":"user profile info"},"tokenUrl":"/-/token"},"clientCredentials":{"scopes":{"openid":"standard oidc scope","profile":"user profile info"},"tokenUrl":"/-/token"},"password":{"scopes":{"openid":"standard oidc scope","profile":"user profile info"},"tokenUrl":"/-/token"}},"type":"oauth2"},"oidc":{"description":"OpenID Connect discovery","openIdConnectUrl":"/.well-known/openid-configuration","type":"openIdConnect"}}},"info":{"description":"Auto-generated OpenAPI specification for KDex Host","title":"KDex Host - rsi-dev","version":"1.0.0"},"openapi":"3.0.0","paths":{"/":{"description":"HTML page Home","get":{"description":"Get HTML for Home","operationId":"page-home-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Home"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/:read"]}],"summary":"Get Home","tags":["page-home","page"]},"summary":"Page Home","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/-/apitokens/mint":{"description":"Mints a new stateless PASETO API token for a given subject and audience.","post":{"description":"POST to mint a new PASETO API token","operationId":"apitoken-mint-post","requestBody":{"content":{"application/json":{"schema":{"properties":{"act":{"type":"string"},"aud":{"type":"string"},"scp":{"type":"string"},"sub":{"type":"string"},"ttl":{"type":"string"}},"required":["aud","sub"],"type":"object"}}},"description":"Mint request body"},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"token":{"type":"string"}},"type":"object"}}},"description":"Minted PASETO Token"},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"description":"Forbidden"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["apitokens:mint"]}],"summary":"Mint PASETO API Token","tags":["system","apitoken","auth"]},"summary":"Mint PASETO API token","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/apitokens/revoke":{"description":"Revokes PASETO API tokens by their signed string or metadata.","post":{"description":"POST to revoke PASETO API tokens","operationId":"apitoken-revoke-post","requestBody":{"content":{"application/json":{"schema":{"properties":{"act":{"type":"string"},"aud":{"type":"string"},"sub":{"type":"string"},"token":{"type":"string"},"ttl":{"type":"string"}},"type":"object"}}},"description":"Revoke request body"},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"status":{"type":"string"}},"type":"object"}}},"description":"Revocation Confirmation"},"400":{"$ref":"#/components/responses/BadRequest"},"403":{"description":"Forbidden"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["apitokens:revoke"]}],"summary":"Revoke PASETO API Token","tags":["system","apitoken","auth"]},"summary":"Revoke PASETO API token","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/apitokens/verify":{"description":"Verifies a PASETO API token and returns its decoded claims.","post":{"description":"POST to verify a PASETO API token","operationId":"apitoken-verify-post","requestBody":{"content":{"application/json":{"schema":{"properties":{"token":{"type":"string"}},"required":["token"],"type":"object"}}},"description":"Verify request body"},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"act":{"type":"string"},"aud":{"type":"string"},"exp":{"type":"integer"},"iat":{"type":"integer"},"iss":{"type":"string"},"jti":{"type":"string"},"kid":{"type":"string"},"nbf":{"type":"integer"},"scp":{"type":"string"},"sub":{"type":"string"}},"type":"object"}}},"description":"Verified Token Claims"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Verify PASETO API Token","tags":["system","apitoken","auth"]},"summary":"Verify PASETO API token","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/check":{"description":"Enables checking multiple resource entitlements for the current user in a single request.","post":{"description":"POST a list of resource identifiers to check authorization.","operationId":"check-post","requestBody":{"content":{"application/json":{"schema":{"properties":{"checks":{"items":{"type":"string"},"type":"array"}},"required":["checks"],"type":"object"}}},"description":"Check request body containing resource identifiers"},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"passed":{"items":{"type":"string"},"type":"array"}},"type":"object"}}},"description":"Subset of resource identifiers that passed the check"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Check Entitlements","tags":["system","auth"]},"summary":"Check multiple entitlements","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/login":{"description":"Provides the login experience","get":{"description":"GET the login view","operationId":"login-get","parameters":[{"description":"The URL to redirect to after successful login","in":"query","name":"return","schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML login page"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Get login experience","tags":["system","login","auth"]},"post":{"description":"POST to login action","operationId":"login-post","responses":{"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"}},"summary":"Login action","tags":["system","login","auth"]},"summary":"Login experience","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/login/{path}":{"description":"Serves the login page shell for any sub-path beneath /-/login, enabling client-side routing between login views following the @kdex/ui app router pattern.","get":{"description":"GET the login shell for a client-side route. The captured path is not interpreted server-side; every sub-path returns the same shell and the client router selects the active view from the URL. Because the login page is mounted under the reserved /-/ prefix (the app router's default path separator), a client hosting a router here must configure a data-path-separator that does not contain /-/.","operationId":"login-clientroute-get","parameters":[{"allowReserved":true,"description":"Client-side route sub-path (e.g. viewport/appId/appPath); consumed by the @kdex/ui app router, not the server","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}},{"description":"The URL to redirect to after successful login","in":"query","name":"return","schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML login page shell"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Get login experience (client-side route)","tags":["system","login","auth"]},"summary":"Login experience client-side routing","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/logout":{"description":"Provides the logout experience","post":{"description":"POST to logout action","operationId":"logout-post","responses":{"302":{"$ref":"#/components/responses/Found"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Logout action","tags":["system","logout","auth"]},"summary":"Logout experience","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/modules/{path}":{"description":"Backend service for serving npm package modules","get":{"description":"GET Backend service for serving npm package modules","operationId":"packages-get","parameters":[{"allowReserved":true,"description":"The path to the static resource","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"*/*":{"schema":{"format":"binary","type":"string"}}},"description":"Static content","headers":{"Content-Type":{"description":"The MIME type of the file (image/png, text/css, text/html, etc.)","schema":{"type":"string"}}}},"404":{"description":"Resource not found"}},"summary":"GET Package Modules","tags":["backend"]},"summary":"Package Modules","x-kdex-metadata":{"contact":{}},"x-kdex-type":"BACKEND"},"/-/navigation/{navKey}/{l10n}/{basePathMinusLeadingSlash}":{"description":"Dynamic HTML navigation components, supporting localization and breadcrumb contexts.","get":{"description":"GET Dynamic HTML navigation","operationId":"navigation-get","parameters":[{"allowReserved":true,"description":"The base path without the leading slash","in":"path","name":"basePathMinusLeadingSlash","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}},{"description":"The language tag","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"description":"The navigation key","in":"path","name":"navKey","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML navigation fragment"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Dynamic HTML navigation","tags":["system","navigation"]},"summary":"Dynamic HTML navigation components","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/oauth/authorize":{"description":"The OAuth2 authorization endpoint","get":{"description":"GET to start authorization flow","operationId":"authorize-get","parameters":[{"description":"The client ID","in":"query","name":"client_id","schema":{"type":"string"}},{"description":"The redirect URI","in":"query","name":"redirect_uri","schema":{"type":"string"}},{"description":"The response type (must be 'code')","in":"query","name":"response_type","schema":{"type":"string"}},{"description":"The requested scopes","in":"query","name":"scope","schema":{"type":"string"}},{"description":"The state parameter for CSRF protection","in":"query","name":"state","schema":{"type":"string"}}],"responses":{"302":{"$ref":"#/components/responses/Found"},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"OAuth2 Authorization","tags":["system","oauth2","auth"]},"summary":"OAuth2 authorization","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/openapi":{"description":"Serves the generated OpenAPI 3.0 specification for this host.","get":{"description":"GET OpenAPI 3.0 Spec","operationId":"openapi-get","parameters":[{"description":"Filter by paths","explode":true,"in":"query","name":"path","schema":{"items":{"type":"string"},"type":"array"}},{"description":"Filter by tags","explode":true,"in":"query","name":"tag","schema":{"items":{"type":"string"},"type":"array"}},{"description":"Filter by path types","explode":true,"in":"query","name":"type","schema":{"items":{"type":"string"},"type":"array"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"OpenAPI documentation"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"OpenAPI 3.0 Spec","tags":["system","openapi"]},"summary":"Generated OpenAPI 3.0 specification","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/schemas":{"description":"Lists all registered JSON schemas and their URLs.","get":{"description":"List all schemas","operationId":"schema-list","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"properties":{"name":{"type":"string"},"urls":{"items":{"type":"string"},"type":"array"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"Schema list"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Schema List","tags":["system","jsonschema","schema","openapi"]},"summary":"List all schemas","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/schemas/{path}":{"description":"Serves individual JSONschema from the registered OpenAPI specifications. The path should be in the format /-/schemas/{basePath}/{schemaName} (e.g., /-/schemas/v1/users/User) or simply /-/schemas/{schemaName} for a global lookup.","get":{"description":"GET JSONschema","operationId":"schema-get","parameters":[{"allowReserved":true,"description":"The schema path (e.g., v1/users/User or User)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"object"}}},"description":"JSONschema fragment"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"JSONschema","tags":["system","jsonschema","schema","openapi"]},"summary":"JSONschema Provider","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/state":{"description":"Returns the current authenticated session state (claims) without requiring the client to parse the JWT.","get":{"description":"GET authenticated session state","operationId":"state-get","responses":{"200":{"content":{"application/json":{"schema":{"format":"json","type":"object"}}},"description":"Current session claims"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Authenticated session state","tags":["system","state","auth"]},"summary":"The current authenticated session state (claims)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/theme/{path}":{"description":"Backend service for KDex theme knowdrive-theme assets","get":{"description":"GET Backend service for KDex theme knowdrive-theme assets","operationId":"knowdrive-theme-get","parameters":[{"allowReserved":true,"description":"The path to the static resource","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"*/*":{"schema":{"format":"binary","type":"string"}}},"description":"Static content","headers":{"Content-Type":{"description":"The MIME type of the file (image/png, text/css, text/html, etc.)","schema":{"type":"string"}}}},"404":{"description":"Resource not found"}},"summary":"GET Theme Assets: knowdrive-theme","tags":["backend"]},"summary":"Theme Assets: knowdrive-theme","x-kdex-metadata":{"contact":{}},"x-kdex-type":"BACKEND"},"/-/token":{"description":"The OAuth2 token endpoint","post":{"description":"POST to exchange credentials for a token","operationId":"token-post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"properties":{"client_id":{"type":"string"},"client_secret":{"type":"string"},"code":{"type":"string"},"grant_type":{"type":"string"},"password":{"type":"string"},"redirect_uri":{"type":"string"},"scope":{"type":"string"},"username":{"type":"string"}},"required":["grant_type","client_id"],"type":"object"}}},"description":"Token request body"},"responses":{"200":{"content":{"application/json":{"schema":{"format":"json","type":"object"}}},"description":"Token Response"},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"OAuth2 Token","tags":["system","oauth2","auth"]},"summary":"The OAuth2 token endpoint","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/-/translation/{l10n}":{"description":"Provides localization keys and their translated values for a given language tag as JSON.","get":{"description":"GET localization keys and their translated values","operationId":"translation-get","parameters":[{"description":"Filter by specific translation keys","explode":true,"in":"query","name":"key","schema":{"items":{"type":"string"},"type":"array"}},{"description":"The language tag","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"}}},"description":"JSON translation map"},"400":{"$ref":"#/components/responses/BadRequest"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Localization keys and their translated values","tags":["system","translation","localization"]},"summary":"Localization keys and their translated values","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/.well-known/jwks.json":{"description":"Serve the JWT key set","get":{"description":"GET the JWT key set","operationId":"jwks-get","responses":{"200":{"content":{"application/json":{"schema":{"format":"json","type":"string"}}},"description":"JWKS"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"The JWKS","tags":["system","jwks","jwt","auth"]},"summary":"The JWT key set","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/.well-known/oauth-authorization-server":{"description":"Serve the OAuth 2.0 Authorization Server configuration","get":{"description":"GET the OAuth 2.0 Authorization Server configuration","operationId":"oauth2-authorization-server-get","responses":{"200":{"content":{"application/json":{"schema":{"format":"json","type":"object"}}},"description":"OpenID Configuration"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"OAuth 2.0 Authorization Server configuration","tags":["system","oidc","auth"]},"summary":"The OAuth 2.0 Authorization Server configuration","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/.well-known/openid-configuration":{"description":"Serve the OpenID configuration","get":{"description":"GET the OpenID configuration","operationId":"discovery-get","responses":{"200":{"content":{"application/json":{"schema":{"format":"json","type":"object"}}},"description":"OpenID Configuration"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"OpenID Discovery","tags":["system","oidc","auth"]},"summary":"The OpenID configuration","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/.well-known/pks.json":{"description":"Returns the public keys for verifying PASETO tokens in a format similar to JWKS but for PASETO v4.public keys.","get":{"description":"GET the public keys for PASETO verification","operationId":"apitoken-discovery-get","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"keys":{"items":{"properties":{"alg":{"type":"string"},"key":{"type":"string"},"kid":{"type":"string"}},"type":"object"},"type":"array"}},"type":"object"}}},"description":"PASETO Public Keys"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"PASETO Public Keys Discovery","tags":["system","apitoken","auth"]},"summary":"PASETO public keys discovery","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/api/v1/events":{"get":{"operationId":"streamEvents","parameters":[{"description":"Optional event-URI prefix filter (the only query knowdb 0.14.0 exposes on /v1/events; per-store scoping is by the caller's entitlements + client-side filtering on the event's vector_store_id).","in":"query","name":"prefix","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"text/event-stream":{"schema":{"description":"Server-Sent Events stream. Each event is a UTF-8 text line in the SSE wire format (data: ..., event: ..., id: ...).","type":"string"}}},"description":"SSE stream of worker events"}},"security":[{"bearer":["functions:/api/v1/events:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/events:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/events:read","vector_stores:*:read"]}],"summary":"Server-Sent-Events stream of worker events (optional prefix filter)","tags":["knowdb","events"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files":{"get":{"operationId":"listFiles","parameters":[{"in":"query","name":"after","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"description":"Sort direction: `asc` | `desc` (default `asc`).","in":"query","name":"order","schema":{"description":"Sort direction for list endpoints. Default is `asc`.","enum":["asc","desc"],"nullable":true,"type":"string"}},{"in":"query","name":"prefix","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"purpose","schema":{"nullable":true,"type":"string"}},{"description":"Restrict to a specific vector store (applies only to the /v1/files global list).","in":"query","name":"vector_store_id","schema":{"nullable":true,"type":"string"}},{"description":"Filter by MIME type. Use 'prefix/*' for wildcard family.","in":"query","name":"mime","schema":{"nullable":true,"type":"string"}},{"description":"Filter by IngestCategory (knowdb src/ingest.rs): tabular | text | image | audio | video | code | tools | skills | notebook | spreadsheet | columnar | unknown.","in":"query","name":"category","schema":{"enum":["tabular","text","image","audio","video","code","tools","skills","notebook","spreadsheet","columnar","unknown"],"nullable":true,"type":"string"}},{"description":"Filter by file status. On `/v1/files` the accepted values are the OpenAI File vocabulary: `uploaded` / `processing` / `processed` / `error`. On `/v1/vector_stores/{id}/files` the accepted values are the OpenAI VectorStoreFile vocabulary: `in_progress` / `completed` / `failed` / `cancelled`. The handler translates these to internal `content.status` values (which are exposed verbatim on responses via the `phase` field). Issue #36.\nQuarantined files (internal `content.status = quarantined`) read as `error` (File vocab) / `failed` (VS-files vocab) and are returned by those filter values; use the `phase` field to distinguish them from genuine `error` rows.\n`fetching` is rejected — use /v1/vector_stores/{id}/stats for in-flight URL-ingest counts.","in":"query","name":"status","schema":{"nullable":true,"type":"string"}},{"description":"Filter by the raw internal lifecycle phase — the SAME vocabulary surfaced on the response `phase` field: `pending` / `text_extracted` / `chunked` / `completed` / `error` / `quarantined` / `fetching`. Unlike `status` (a coarse OpenAI bucket), `phase` isolates a single state — e.g. `phase=quarantined` returns ONLY quarantined files, not the whole `error`/`failed` bucket. Route-independent (same vocabulary on both list routes). Mutually exclusive with `status`: supplying both is a 400. Unknown values are a 400.","in":"query","name":"phase","schema":{"nullable":true,"type":"string"}},{"description":"ISO 8601 timestamp or Unix seconds; inclusive lower bound on files.created_at.","in":"query","name":"created_after","schema":{"nullable":true,"type":"string"}},{"description":"ISO 8601 timestamp or Unix seconds; exclusive upper bound on files.created_at.","in":"query","name":"created_before","schema":{"nullable":true,"type":"string"}},{"description":"Inclusive lower bound on content.size (bytes).","in":"query","name":"size_min","schema":{"format":"int64","minimum":0,"nullable":true,"type":"integer"}},{"description":"Inclusive upper bound on content.size (bytes).","in":"query","name":"size_max","schema":{"format":"int64","minimum":0,"nullable":true,"type":"integer"}},{"description":"Comma-separated tag list; match files containing at least one.","in":"query","name":"tags_any","schema":{"nullable":true,"type":"string"}},{"description":"Comma-separated tag list; match files containing all.","in":"query","name":"tags_all","schema":{"nullable":true,"type":"string"}},{"description":"Comma-separated tag list; match files containing none.","in":"query","name":"tags_none","schema":{"nullable":true,"type":"string"}},{"description":"Target vector store for an unscoped request — overrides the default `system` store. Lower precedence than a body/query `vector_store_id`.","in":"header","name":"X-Vector-Store-Id","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListFilesResponse"}}},"description":"List of files"},"400":{"description":"Invalid query parameters"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/files:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/files:read","vector_stores:{vector_store_id}:read"]}],"summary":"List files","tags":["knowdb","files"],"x-entitlement-binding":{"vector_store_id":[{"in":"query","name":"vector_store_id"},{"in":"header","name":"X-Vector-Store-Id"}]}},"post":{"operationId":"createFile","parameters":[{"description":"Target vector store for an unscoped request — overrides the default `system` store. Lower precedence than a body/query `vector_store_id`.","in":"header","name":"X-Vector-Store-Id","schema":{"nullable":true,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"metadata":{"additionalProperties":true,"description":"Free-form metadata object attached to the file.","nullable":true,"type":"object"},"mime_hint":{"description":"Advisory MIME hint (server sniffs the downloaded bytes; not authoritative — contrast the multipart `mime_type`).","nullable":true,"type":"string"},"path":{"description":"Logical path for the file within the vector store.","type":"string"},"purpose":{"nullable":true,"type":"string"},"tags":{"items":{"type":"string"},"nullable":true,"type":"array"},"url":{"description":"HTTP/HTTPS URL to fetch.","type":"string"},"vector_store_id":{"description":"Target vector store name or ID.","type":"string"}},"required":["url","vector_store_id","path"],"type":"object"}},"multipart/form-data":{"schema":{"properties":{"file":{"format":"binary","type":"string"},"file_id":{"description":"Target an existing file for `purpose=rename`/`update_metadata`.","nullable":true,"type":"string"},"filename":{"description":"Overrides the `file` part's filename / logical path.","nullable":true,"type":"string"},"mime_type":{"description":"Authoritative client MIME override (knowdb #285).","nullable":true,"type":"string"},"purpose":{"description":"Upload purpose. Also a mode switch: `rename` / `update_metadata` mutate an existing file (require `file_id`).","type":"string"},"tags":{"description":"Comma-separated tag list applied to the file on upload.","nullable":true,"type":"string"},"vector_store_id":{"description":"Target vector store; body wins over the X-Vector-Store-Id header.","nullable":true,"type":"string"}},"required":["file","purpose"],"type":"object"}}},"description":"Either a multipart file upload OR (Content-Type: application/json) a deferred URL-pull fetch job — knowdb's create_file handler dispatches on Content-Type. utoipa wires only the multipart shape and declares just `file`+`purpose`, so /openapi under-documented the extra multipart fields AND the entire JSON URL-pull body. knowdb mmstore #341.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileObject"}}},"description":"File created (multipart upload). Returns an OpenAIFile object."},"201":{"description":"URL-pull fetch job enqueued (application/json variant — deferred ingest)."},"400":{"description":"Malformed multipart body, invalid JSON, invalid path, or SSRF-blocked URL"},"404":{"description":"Vector store not found (URL-pull variant)"},"413":{"description":"Per-VS quota exceeded"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:create","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:create","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:create","vector_stores:*:write"]}],"summary":"Upload a file","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/batch_delete":{"post":{"operationId":"batchDeleteFiles","requestBody":{"content":{"application/json":{"schema":{"properties":{"file_ids":{"description":"File ids to delete (1..=`BULK_FILES_MAX_ITEMS`).","items":{"type":"string"},"type":"array"}},"required":["file_ids"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"description":"Response for the bulk file operations (#17).","properties":{"declined":{"description":"knowdb #507: items the server REFUSED to guess at — present only on `batch_remime_result`, where `total = succeeded + failed + declined`. A decline is NOT a failure; folding it into `failed` would read to a retry loop as \"each of these failed\" rather than \"these cannot be repaired this way\". Absent on the three pre-#507 envelopes, which keep their exact wire shape.","minimum":0,"nullable":true,"type":"integer"},"failed":{"minimum":0,"type":"integer"},"object":{"description":"`batch_delete_result`, `batch_tags_result`, `batch_retag_result` or `batch_remime_result`.","type":"string"},"results":{"items":{"description":"Per-item outcome (#17). `status` is one of `deleted`/`updated`/`not_found`/`error`. `error` carries the message only for the `error` status.","properties":{"error":{"nullable":true,"type":"string"},"file_id":{"type":"string"},"index":{"minimum":0,"type":"integer"},"reason":{"description":"knowdb #507: a stable code for a `declined` item, so a client sweeping a large corpus can bucket refusals without string-matching `error`. Absent on every pre-#507 surface.","nullable":true,"type":"string"},"status":{"type":"string"}},"required":["index","file_id","status"],"type":"object"},"type":"array"},"succeeded":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"}},"required":["object","total","succeeded","failed","results"],"type":"object"}}},"description":"Per-file delete outcomes (best-effort)."},"400":{"description":"Empty `file_ids` or more than the bulk maximum"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:delete","vector_stores:*:delete"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:delete","vector_stores:*:delete"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:delete","vector_stores:*:delete"]}],"summary":"Bulk-delete files (best-effort)","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/batch_remime":{"post":{"operationId":"batchRemimeFiles","requestBody":{"content":{"application/json":{"schema":{"description":"Request body for `POST /v1/files/batch_remime` (#507).","properties":{"file_ids":{"description":"File ids to repair (1..=`BULK_FILES_MAX_ITEMS`).","items":{"type":"string"},"type":"array"},"if_mime":{"description":"**Required** — the `mime:` value the caller expects to replace, or `null` to apply only to files with NO `mime:` tag. One precondition for the whole batch: a sweep repairs ONE known-wrong value at a time, which is what makes it safe to run over a corpus the caller has not inspected file by file.","nullable":true,"type":"string"}},"required":["file_ids"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"description":"Response for the bulk file operations (#17).","properties":{"declined":{"description":"knowdb #507: items the server REFUSED to guess at — present only on `batch_remime_result`, where `total = succeeded + failed + declined`. A decline is NOT a failure; folding it into `failed` would read to a retry loop as \"each of these failed\" rather than \"these cannot be repaired this way\". Absent on the three pre-#507 envelopes, which keep their exact wire shape.","minimum":0,"nullable":true,"type":"integer"},"failed":{"minimum":0,"type":"integer"},"object":{"description":"`batch_delete_result`, `batch_tags_result`, `batch_retag_result` or `batch_remime_result`.","type":"string"},"results":{"items":{"description":"Per-item outcome (#17). `status` is one of `updated`/`not_found`/`error`, or `declined` on this surface. `error` carries the message only for the `error` status.","properties":{"error":{"nullable":true,"type":"string"},"file_id":{"type":"string"},"index":{"minimum":0,"type":"integer"},"reason":{"description":"knowdb #507: a stable code for a `declined` item, so a client sweeping a large corpus can bucket refusals without string-matching `error`. Absent on every pre-#507 surface.","nullable":true,"type":"string"},"status":{"type":"string"}},"required":["index","file_id","status"],"type":"object"},"type":"array"},"succeeded":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"}},"required":["object","total","succeeded","failed","results"],"type":"object"}}},"description":"Per-file outcomes (best-effort). `total = succeeded + failed + declined`."},"400":{"description":"Empty `file_ids`, more than the bulk maximum, or a missing/empty `if_mime`"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update"]}],"summary":"Bulk-replace a wrong `mime:` tag across files (best-effort)","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/batch_retag":{"post":{"operationId":"batchRetagFiles","requestBody":{"content":{"application/json":{"schema":{"properties":{"file_ids":{"description":"File ids to repair (1..=`BULK_FILES_MAX_ITEMS`).","items":{"type":"string"},"type":"array"}},"required":["file_ids"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"description":"Response for the bulk file operations (#17).","properties":{"declined":{"description":"knowdb #507: items the server REFUSED to guess at — present only on `batch_remime_result`, where `total = succeeded + failed + declined`. A decline is NOT a failure; folding it into `failed` would read to a retry loop as \"each of these failed\" rather than \"these cannot be repaired this way\". Absent on the three pre-#507 envelopes, which keep their exact wire shape.","minimum":0,"nullable":true,"type":"integer"},"failed":{"minimum":0,"type":"integer"},"object":{"description":"`batch_delete_result`, `batch_tags_result`, `batch_retag_result` or `batch_remime_result`.","type":"string"},"results":{"items":{"description":"Per-item outcome (#17). `status` is one of `updated`/`not_found`/`error`. `error` carries the message only for the `error` status.","properties":{"error":{"nullable":true,"type":"string"},"file_id":{"type":"string"},"index":{"minimum":0,"type":"integer"},"reason":{"description":"knowdb #507: a stable code for a `declined` item, so a client sweeping a large corpus can bucket refusals without string-matching `error`. Absent on every pre-#507 surface.","nullable":true,"type":"string"},"status":{"type":"string"}},"required":["index","file_id","status"],"type":"object"},"type":"array"},"succeeded":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"}},"required":["object","total","succeeded","failed","results"],"type":"object"}}},"description":"Per-file tag-repair outcomes (best-effort)."},"400":{"description":"Empty `file_ids` or more than the bulk maximum"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]}],"summary":"Bulk re-derive tags across files (best-effort)","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/batch_tags":{"post":{"operationId":"batchTagFiles","requestBody":{"content":{"application/json":{"schema":{"properties":{"file_ids":{"description":"File ids to re-tag (1..=`BULK_FILES_MAX_ITEMS`).","items":{"type":"string"},"type":"array"},"tags_add":{"description":"Tags to add to each file (union; deduped). Validated + normalized.","items":{"type":"string"},"type":"array"},"tags_remove":{"description":"Tags to remove from each file (normalized; removing an absent tag is a no-op).","items":{"type":"string"},"type":"array"}},"required":["file_ids"],"type":"object"}}},"description":"At least one of `tags_add`/`tags_remove` must be non-empty.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"description":"Response for the bulk file operations (#17).","properties":{"declined":{"description":"knowdb #507: items the server REFUSED to guess at — present only on `batch_remime_result`, where `total = succeeded + failed + declined`. A decline is NOT a failure; folding it into `failed` would read to a retry loop as \"each of these failed\" rather than \"these cannot be repaired this way\". Absent on the three pre-#507 envelopes, which keep their exact wire shape.","minimum":0,"nullable":true,"type":"integer"},"failed":{"minimum":0,"type":"integer"},"object":{"description":"`batch_delete_result`, `batch_tags_result`, `batch_retag_result` or `batch_remime_result`.","type":"string"},"results":{"items":{"description":"Per-item outcome (#17). `status` is one of `deleted`/`updated`/`not_found`/`error`. `error` carries the message only for the `error` status.","properties":{"error":{"nullable":true,"type":"string"},"file_id":{"type":"string"},"index":{"minimum":0,"type":"integer"},"reason":{"description":"knowdb #507: a stable code for a `declined` item, so a client sweeping a large corpus can bucket refusals without string-matching `error`. Absent on every pre-#507 surface.","nullable":true,"type":"string"},"status":{"type":"string"}},"required":["index","file_id","status"],"type":"object"},"type":"array"},"succeeded":{"minimum":0,"type":"integer"},"total":{"minimum":0,"type":"integer"}},"required":["object","total","succeeded","failed","results"],"type":"object"}}},"description":"Per-file tag-update outcomes (best-effort)."},"400":{"description":"Empty/over-limit `file_ids`, no add/remove, or an invalid tag"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]}],"summary":"Bulk add/remove tags across files (best-effort)","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}":{"delete":{"operationId":"deleteFile","parameters":[{"description":"The ID of the file to delete (this maps to the URI/filename in knowdb)","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"#379: optional CAS precondition — the resource's current `etag`. `*` matches any existing resource. A mismatch is refused with 412 and applies nothing; omitting the header is an unconditional write.","in":"header","name":"If-Match","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedFile"}}},"description":"File deleted successfully"},"404":{"description":"File not found"},"412":{"description":"`If-Match` precondition failed — the resource changed since the validator was issued. Body carries `current_etag`; nothing was applied."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:delete","vector_stores:*:delete"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:delete","vector_stores:*:delete"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:delete","vector_stores:*:delete"]}],"summary":"Delete file","tags":["knowdb","files"]},"get":{"operationId":"getFile","parameters":[{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileObject"}}},"description":"File metadata"},"404":{"description":"Not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/files:read","vector_stores:*:read"]}],"summary":"Get file metadata","tags":["knowdb","files"]},"patch":{"operationId":"patchFile","parameters":[{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"#379: optional CAS precondition — the resource's current `etag`. `*` matches any existing resource. A mismatch is refused with 412 and applies nothing; omitting the header is an unconditional write.","in":"header","name":"If-Match","schema":{"nullable":true,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"tags":{"description":"New tag list. Omit to leave tags unchanged; `[]` clears all tags. Tags are normalized (trimmed + lowercased) and validated `[a-z0-9._:/-]`.","items":{"type":"string"},"nullable":true,"type":"array"}},"type":"object"}}},"description":"RFC-7396-style partial update: an omitted field is left unchanged. Today the only mutable field is `tags`.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileObject"}}},"description":"Updated file metadata"},"400":{"description":"Invalid tag (fails normalization / `[a-z0-9._:/-]`)"},"404":{"description":"Not found (or cross-VS denial for a scoped token)"},"409":{"description":"Superseded version (the file was re-versioned concurrently)"},"412":{"description":"`If-Match` precondition failed — the resource changed since the validator was issued. Body carries `current_etag`; nothing was applied."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]}],"summary":"Modify a file's mutable metadata (PATCH)","tags":["knowdb","files"]},"post":{"operationId":"updateFile","parameters":[{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"#379: optional CAS precondition — the resource's current `etag`. `*` matches any existing resource. A mismatch is refused with 412 and applies nothing; omitting the header is an unconditional write.","in":"header","name":"If-Match","schema":{"nullable":true,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"tags":{"description":"New tag list. Omit to leave tags unchanged; `[]` clears all tags. Tags are normalized (trimmed + lowercased) and validated `[a-z0-9._:/-]`.","items":{"type":"string"},"nullable":true,"type":"array"}},"type":"object"}}},"description":"RFC-7396-style partial update: an omitted field is left unchanged. Today the only mutable field is `tags`.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileObject"}}},"description":"Updated file metadata"},"400":{"description":"Invalid tag (fails normalization / `[a-z0-9._:/-]`)"},"404":{"description":"Not found (or cross-VS denial for a scoped token)"},"409":{"description":"Superseded version (the file was re-versioned concurrently)"},"412":{"description":"`If-Match` precondition failed — the resource changed since the validator was issued. Body carries `current_etag`; nothing was applied."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]}],"summary":"Modify a file's mutable metadata (POST)","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/atoms":{"get":{"operationId":"listFileAtoms","parameters":[{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"Opaque pagination cursor from a previous page's `next_after`.","in":"query","name":"after","schema":{"nullable":true,"type":"string"}},{"description":"Page size (1..=`MAX_ATOMS_PER_LIST_PAGE`). `0` is rejected.","in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"description":"Atom ordering by `sequence_index`: `asc` (default) or `desc`.","in":"query","name":"order","schema":{"nullable":true,"type":"string"}},{"description":"Include the raw `binary` segment on each atom (default `false`).","in":"query","name":"include_binary","schema":{"nullable":true,"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAtomsResponse"}}},"description":"One page of the file's atoms"},"400":{"description":"Invalid cursor or limit"},"404":{"description":"File not found or not visible to the caller"}},"security":[{"bearer":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/files:read","vector_stores:*:read"]}],"summary":"List a file's atoms in sequence order","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/content":{"get":{"operationId":"getFileContent","parameters":[{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"Override Content-Disposition (default: attachment)","in":"query","name":"disposition","schema":{"type":"string"}},{"description":"RFC 7233 byte range, single-range only (e.g. `bytes=0-1023`, `bytes=1024-`, `bytes=-512`)","in":"header","name":"range","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"description":"Whole file. Carries Accept-Ranges: bytes."},"206":{"description":"Partial content for a Range request. Carries Content-Range + Accept-Ranges."},"404":{"description":"Not found"},"416":{"description":"Requested range not satisfiable; multi-range or out-of-bounds."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/files:read","vector_stores:*:read"]}],"summary":"Stream file content","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/extractions":{"get":{"operationId":"listFileExtractions","parameters":[{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"description":"The `content.extractions` array produced by the extraction phase; empty for a not-yet-extracted, pure-text-short-circuited, or extraction-less file.","items":{"type":"string"},"type":"array"},"file_id":{"type":"string"},"object":{"type":"string"}},"required":["object","file_id","data"],"type":"object"}}},"description":"The file content's extraction outputs (may be empty)."},"404":{"description":"File not found or not visible to the caller"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/files:read","vector_stores:*:read"]}],"summary":"List a file content's extraction outputs","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/remime":{"post":{"operationId":"remimeFile","parameters":[{"description":"The file whose `mime:` tag to re-derive.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"description":"Body shared by both remime routes.","properties":{"if_mime":{"description":"**Required.** The `mime:` value the caller expects to replace, or `null` to apply only when the file has no `mime:` tag. Omitting the field is a 400 — there is no \"fix whatever is there\" mode, because a client MIME hint is authoritative and unrecorded.","nullable":true,"type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"description":"Response body for `POST /v1/files/{file_id}/remime`.","properties":{"detail":{"description":"Human-readable explanation of a decline.","nullable":true,"type":"string"},"file_id":{"type":"string"},"reason":{"description":"Present only when `status == \"declined\"`: `precondition_mismatch` | `no_extension` | `byte_detected` | `unknown_extension` | `underivable`.","nullable":true,"type":"string"},"status":{"description":"`updated` | `no_change` | `declined`.","type":"string"},"tags":{"description":"The file's tags after the op. Unchanged on `no_change` and `declined`.","items":{"type":"string"},"type":"array"}},"required":["file_id","status","tags"],"type":"object"}}},"description":"Re-derived, already correct, or DECLINED — all three are 200. A decline (precondition mismatch, or a MIME the filename cannot settle) means nothing the caller can retry changes the answer."},"400":{"description":"`if_mime` omitted, or supplied as an empty string"},"404":{"description":"Unknown file id, or the caller may not write to its vector store"},"409":{"description":"Superseded (not the current version)"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update"]}],"summary":"Re-derive a file's `mime:` tag from its filename","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/reprocess":{"post":{"operationId":"reprocessFile","parameters":[{"description":"The ID of the file to reprocess.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}}],"responses":{"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReprocessResponse"}}},"description":"Reprocess accepted; worker pipeline will rebuild from the blob."},"404":{"description":"File not found"},"409":{"description":"Source blob is absent — the file cannot be rebuilt without its bytes."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]}],"summary":"Reset a file's derived state and rebuild it from the persisted blob","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/retag":{"post":{"operationId":"retagFile","parameters":[{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"description":"Deliberately lean (not a full `OpenAIFile`) — the op is metadata-only (2 row reads + 1 `update_file_attrs`), so the response mirrors that cost.","properties":{"file_id":{"type":"string"},"tags":{"description":"The full tag set after the additive re-derivation (existing ∪ derived `dir:`/`mime:`/`charset:` tags). Idempotent — re-running on an unchanged file reproduces it.","items":{"type":"string"},"type":"array"}},"required":["file_id","tags"],"type":"object"}}},"description":"Repaired tag set (existing ∪ re-derived dir:/mime:/charset:)"},"404":{"description":"File not found (or not visible to this caller's vector store)"},"409":{"description":"File is a superseded (non-current) version"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]}],"summary":"Re-derive a file's derived (dir:/mime:/charset:) tags","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/revert":{"post":{"operationId":"revertFile","parameters":[{"description":"The ID of the historical version whose content_hash to roll the head back to. May be any file_id (current or superseded) in the path's version chain.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"#379: optional CAS precondition — the resource's current `etag`. `*` matches any existing resource. A mismatch is refused with 412 and applies nothing; omitting the header is an unconditional write.","in":"header","name":"If-Match","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileObject"}}},"description":"Revert succeeded; the body is the new current version (a fresh file_id at version+1)."},"404":{"description":"File not found"},"409":{"description":"Revert would be a no-op (`{\"error\":\"idempotent_revert\",...}` — named version's content already matches head), or named version's content has been garbage-collected (`{\"error\":\"content_gc\",...}`). See #49."},"412":{"description":"`If-Match` precondition failed — the resource changed since the validator was issued. Body carries `current_etag`; nothing was applied."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/files:read","functions:/api/v1/files:update","vector_stores:*:write"]}],"summary":"Revert file to prior version","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/files/{file_id}/wait":{"get":{"operationId":"waitFileStatus","parameters":[{"description":"The file to wait on.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"Terminal OpenAI File status to wait for (`processed` or `error`). Only terminal states are honored; a non-terminal or unknown value is rejected with 400. Omit to return on any terminal state.","in":"query","name":"status","schema":{"nullable":true,"type":"string"}},{"description":"Max seconds to block. Clamped to the server ceiling (`limits.max_wait_seconds` in `/v1/capabilities`); defaults to the server default when omitted.","in":"query","name":"timeout","schema":{"format":"int64","minimum":0,"nullable":true,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"file":{"$ref":"#/components/schemas/FileObject"},"reached":{"description":"`true` if the file's status equals the requested `status` (or, when no `status` was requested, if it reached any terminal state).","type":"boolean"},"timed_out":{"description":"`true` if the wait hit its timeout before the file reached a terminal state. When `true`, `file` reflects the last-observed (non-terminal) state.","type":"boolean"}},"required":["file","reached","timed_out"],"type":"object"}}},"description":"The file settled (or the wait timed out). See `reached`/`timed_out`."},"400":{"description":"Unknown `status` value"},"404":{"description":"File not found / not permitted"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/files:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/files:read","vector_stores:*:read"]}],"summary":"Bounded wait until a file reaches a terminal status","tags":["knowdb","files"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/ingest":{"post":{"operationId":"ingest","parameters":[{"description":"Target vector store for an unscoped request — overrides the default `system` store. Lower precedence than a body `vector_store_id` field.","in":"header","name":"X-Vector-Store-Id","schema":{"nullable":true,"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"description":"One or more files to ingest.","items":{"format":"binary","type":"string"},"type":"array"},"mime_type":{"description":"Optional batch-level MIME hint (knowdb #292/#285) applied to any `file` part that carries no explicit Content-Type; a per-part Content-Type still wins. The handler reads it (api.rs ingest_handler) but knowdb's IngestMultipartRequest ToSchema omits it, so /openapi hid it — surfaced here.","nullable":true,"type":"string"},"tags":{"description":"Optional comma-separated tags applied to every ingested file.","nullable":true,"type":"string"},"vector_store_id":{"description":"Optional target vector store id. Takes precedence over the X-Vector-Store-Id header; falls through to `system` when neither is set.","nullable":true,"type":"string"}},"required":["file"],"type":"object"}}},"description":"Multipart batch upload — one or more files plus optional tags/target.","required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"failed":{"description":"#292: per-file failures in the best-effort batch. Empty on a fully-successful batch.","items":{"properties":{"error":{"type":"string"},"file_name":{"type":"string"}},"required":["file_name","error"],"type":"object"},"type":"array"},"files":{"description":"The created file rows (queued at `pending`).","items":{"$ref":"#/components/schemas/FileObject"},"type":"array"},"message":{"type":"string"},"processing_time_ms":{"format":"int64","minimum":0,"type":"integer"},"status":{"type":"string"}},"required":["status","files","message","processing_time_ms"],"type":"object"}}},"description":"Files queued for background processing."},"400":{"description":"Malformed multipart body or invalid path"},"413":{"description":"Per-VS quota exceeded"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/ingest:read","functions:/api/v1/ingest:create","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/ingest:read","functions:/api/v1/ingest:create","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/ingest:read","functions:/api/v1/ingest:create","vector_stores:*:write"]}],"summary":"Batch-ingest one or more files into a vector store (multipart)","tags":["knowdb","ingest"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/mcp":{"delete":{"operationId":"mcpTerminate","responses":{"405":{"description":"Session termination not supported: sessions are stateless, so there is no server-side state to terminate. The client simply drops its session id."}},"security":[{"oauth2":["functions:/api/v1/mcp:read"]},{"bearer":["functions:/api/v1/mcp:read"]},{"apiKeyHeader":["functions:/api/v1/mcp:read"]},{"apiKeyQuery":["functions:/api/v1/mcp:read"]}],"summary":"Terminate MCP session","tags":["knowdb","mcp"]},"get":{"operationId":"mcpStream","responses":{"200":{"content":{"text/event-stream":{"schema":{"type":"string"}}},"description":"Server-to-client SSE notification stream."},"400":{"description":"Missing Mcp-Session-Id header (the SSE stream requires an established session). Matches knowdb's GET /mcp 400 (server.rs)."},"404":{"description":"Unknown/undecodable Mcp-Session-Id (re-initialize). Matches knowdb's GET /mcp 404 (server.rs)."}},"security":[{"oauth2":["functions:/api/v1/mcp:read"]},{"bearer":["functions:/api/v1/mcp:read"]},{"apiKeyHeader":["functions:/api/v1/mcp:read"]},{"apiKeyQuery":["functions:/api/v1/mcp:read"]}],"summary":"Server→client SSE keepalive stream","tags":["knowdb","mcp"]},"post":{"operationId":"mcpRpc","requestBody":{"content":{"application/json":{"schema":{"description":"Single JSON-RPC request OR a batch array. Untagged so serde decides by shape.","oneOf":[{"$ref":"#/components/schemas/JsonRpcRequest"},{"items":{"$ref":"#/components/schemas/JsonRpcRequest"},"type":"array"}]}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}},"description":"JSON-RPC response or batch."},"400":{"description":"Non-initialize request missing the Mcp-Session-Id header, or an unsupported MCP-Protocol-Version."},"404":{"description":"Non-initialize request with an unknown/invalid Mcp-Session-Id (re-initialize)."}},"security":[{"oauth2":["functions:/api/v1/mcp:read"]},{"bearer":["functions:/api/v1/mcp:read"]},{"apiKeyHeader":["functions:/api/v1/mcp:read"]},{"apiKeyQuery":["functions:/api/v1/mcp:read"]}],"summary":"MCP JSON-RPC request or batch (initialize + tool/resource/prompt calls)","tags":["knowdb","mcp"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/search":{"get":{"operationId":"searchText","parameters":[{"description":"Query text. Issue #79: must be non-empty / non-whitespace; empty values are rejected with 400 across every mode.","in":"query","name":"query","required":true,"schema":{"type":"string"}},{"in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"in":"query","name":"offset","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"in":"query","name":"max_distance","schema":{"format":"float","nullable":true,"type":"number"}},{"description":"Search mode. `hybrid` (default), `vector`, or `fts`. Issue #80: unknown values are rejected with 400 rather than silently coerced to `hybrid`. (The former `uri` mode was removed — list a file's atoms via `GET /v1/files/{file_id}/atoms` instead.)","in":"query","name":"mode","schema":{"$ref":"#/components/schemas/SearchMode"}},{"description":"Vector field a `vector`/`hybrid` query is matched against. One of `text` (default), `vision`, or `audio`.","in":"query","name":"search_field","schema":{"$ref":"#/components/schemas/SearchField"}},{"description":"Vector store to search. On the global `GET /v1/search` this selects the store (falling back to the `X-Vector-Store-Id` header, then `system`). On the scoped `GET /v1/vector_stores/{id}/search` route the `{id}` path segment is authoritative and this query param is ignored (#203).","in":"query","name":"vector_store_id","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"include_binary","schema":{"nullable":true,"type":"boolean"}},{"description":"#408: also return atoms belonging to superseded file versions. Default `false`. Superseded versions retain their atoms so `revert` stays a flag flip, but those atoms resolve to no current file and surfaced as hits with null `uri`/`tags`/`file_id`. Filtering them is a bug fix and the default; set `true` only to search history deliberately. Content is shared, so an atom is excluded only when its `content_hash` is referenced EXCLUSIVELY by superseded versions.","in":"query","name":"include_superseded","schema":{"nullable":true,"type":"boolean"}},{"description":"Comma-separated list of tags that every returned atom must carry (intersection / AND semantics). Mime types are tagged at ingest time with the prefix `mime:`, so `tags=mime:application/pdf` filters to PDFs only.","in":"query","name":"tags","schema":{"nullable":true,"type":"string"}},{"description":"Target vector store for an unscoped request — overrides the default `system` store. Lower precedence than a body/query `vector_store_id`.","in":"header","name":"X-Vector-Store-Id","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}},"description":"Successful search"},"400":{"description":"Invalid query parameter (empty `query`, unknown `mode`, or unknown `search_field` value)"},"404":{"description":"Requested vector_store_id not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/search:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/search:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/search:read","vector_stores:{vector_store_id}:read"]}],"summary":"Text query across all stores","tags":["knowdb","search"],"x-entitlement-binding":{"vector_store_id":[{"in":"query","name":"vector_store_id"},{"in":"header","name":"X-Vector-Store-Id"}]}},"post":{"operationId":"searchMultipart","parameters":[{"description":"Target vector store for an unscoped request — overrides the default `system` store. Lower precedence than a body/query `vector_store_id`.","in":"header","name":"X-Vector-Store-Id","schema":{"nullable":true,"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"format":"binary","nullable":true,"type":"string"},"include_binary":{"nullable":true,"type":"boolean"},"include_superseded":{"description":"#408: also return atoms of superseded file versions. Default `false`; parity with the `include_superseded` query param on `GET /v1/search`.","nullable":true,"type":"boolean"},"limit":{"minimum":0,"nullable":true,"type":"integer"},"max_distance":{"format":"float","nullable":true,"type":"number"},"mode":{"$ref":"#/components/schemas/SearchMode"},"offset":{"minimum":0,"nullable":true,"type":"integer"},"search_field":{"description":"Vector field a `vector`/`hybrid` query is matched against.","enum":["text","vision","audio"],"nullable":true,"type":"string"},"tags":{"description":"Comma-separated list of tags; see [`SearchParameters::tags`].","nullable":true,"type":"string"},"text":{"description":"Query text. `query` is also accepted as an alias for this field.","nullable":true,"type":"string"},"vector_store_id":{"nullable":true,"type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}},"description":"Successful media search"},"400":{"description":"Invalid request (unknown mode, empty query with no file, etc.)"}},"security":[{"bearer":["functions:/api/v1/search:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/search:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/search:read","vector_stores:*:read"]}],"summary":"Media (multipart) query across all stores","tags":["knowdb","search"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/uploads":{"post":{"operationId":"initiateUpload","parameters":[{"description":"Target vector store for an unscoped request — overrides the default `system` store. Lower precedence than a body/query `vector_store_id`.\n","in":"header","name":"X-Vector-Store-Id","schema":{"nullable":true,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiateUploadRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadObject"}}},"description":"Upload session created"},"400":{"description":"Invalid request"},"404":{"description":"Body vector_store_id not accessible to the caller (#60)"},"413":{"description":"bytes exceeds max_vs_bytes"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:create","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:create","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:create","vector_stores:*:write"]}],"summary":"Initiate multipart upload","tags":["knowdb","uploads"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/uploads/{upload_id}/cancel":{"post":{"operationId":"cancelUpload","parameters":[{"in":"path","name":"upload_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadObject"}}},"description":"Upload cancelled"},"404":{"description":"Unknown upload_id"},"409":{"description":"Upload already completed"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:delete","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:delete","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:delete","vector_stores:*:write"]}],"summary":"Abort multipart upload","tags":["knowdb","uploads"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/uploads/{upload_id}/complete":{"post":{"operationId":"completeUpload","parameters":[{"description":"Upload session identifier","in":"path","name":"upload_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteUploadRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadObject"}}},"description":"Upload assembled and committed"},"400":{"description":"Bad request (invalid part_ids or digest format)"},"404":{"description":"Upload not found"},"409":{"description":"Digest mismatch or upload in non-completable state"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:update","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:update","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:update","vector_stores:*:write"]}],"summary":"Finalize multipart upload","tags":["knowdb","uploads"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/uploads/{upload_id}/parts":{"post":{"operationId":"uploadPart","parameters":[{"description":"Upload session identifier","in":"path","name":"upload_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"data":{"description":"The raw bytes of this upload chunk.","format":"binary","type":"string"}},"required":["data"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadPartObject"}}},"description":"Part stored"},"404":{"description":"Unknown upload_id"},"409":{"description":"Upload not in pending state"},"413":{"description":"Part exceeds max_write_chunk_bytes"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:create","vector_stores:*:write"]},{"apiKeyHeader":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:create","vector_stores:*:write"]},{"apiKeyQuery":["functions:/api/v1/uploads:read","functions:/api/v1/uploads:create","vector_stores:*:write"]}],"summary":"Append a part to an in-flight upload","tags":["knowdb","uploads"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores":{"get":{"operationId":"listVectorStores","parameters":[{"in":"query","name":"after","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"description":"Sort direction: `asc` | `desc` (default `asc`).","in":"query","name":"order","schema":{"description":"Sort direction for list endpoints. Default is `asc`.","enum":["asc","desc"],"nullable":true,"type":"string"}},{"description":"#310: defaults to TRUE. Return materialized counters only, skipping the per-store compute-on-read scan. In fast mode last_modified_at is null and the files_* breakdown + status_fetching read 0. Pass fast=false for the full scan.","in":"query","name":"fast","schema":{"nullable":true,"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/VectorStoreObject"},"type":"array"},"has_more":{"type":"boolean"},"next_after":{"nullable":true,"type":"string"},"object":{"type":"string"}},"required":["object","data","has_more"],"type":"object"}}},"description":"List of vector stores"},"400":{"description":"Invalid query parameters"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:*:read"]}],"summary":"List vector stores","tags":["knowdb","vector_stores"]},"post":{"operationId":"createVectorStore","requestBody":{"content":{"application/json":{"schema":{"properties":{"capabilities":{"description":"Per-VS feature toggles + quotas (issue #8). Every knob is Option\u003cT\u003e — None means \"fall through to the global default\" (operator-set env var).","nullable":true,"properties":{"audio_embeddings_enabled":{"nullable":true,"type":"boolean"},"chunk_overrides":{"description":"Per-VS chunk-size overrides (#70). Each axis falls through to the global KNOWDB_MIN_CHUNK_SIZE / KNOWDB_MAX_CHUNK_SIZE / KNOWDB_CHUNK_OVERLAP_PERCENT when unset.","nullable":true,"properties":{"max_chunk_size":{"minimum":0,"nullable":true,"type":"integer"},"min_chunk_size":{"minimum":0,"nullable":true,"type":"integer"},"overlap_percent":{"minimum":0,"nullable":true,"type":"integer"}},"type":"object"},"ocr_enabled":{"nullable":true,"type":"boolean"},"quota":{"nullable":true,"properties":{"max_atoms":{"description":"#396: max current-version atoms across all files in this store; composes with global KNOWDB_MAX_VS_ATOMS via min(). None/0 = unlimited per-VS.","format":"int64","minimum":0,"nullable":true,"type":"integer"},"max_bytes":{"format":"int64","minimum":0,"nullable":true,"type":"integer"}},"type":"object"},"vision_embeddings_enabled":{"nullable":true,"type":"boolean"}},"type":"object"},"name":{"type":"string"},"requirements":{"items":{"type":"string"},"nullable":true,"type":"array"}},"required":["name"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreObject"}}},"description":"Vector store created"},"409":{"description":"Vector store name already exists (or is reserved)"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:create","vector_stores_create"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:create","vector_stores_create"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:create","vector_stores_create"]}],"summary":"Create a vector store","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/stats":{"get":{"operationId":"getVectorStoresStats","parameters":[{"description":"Return stores whose name is strictly greater than this cursor, sorted ascending.","in":"query","name":"after","schema":{"nullable":true,"type":"string"}},{"description":"Page size. Clamped to MAX_FLEET_STATS_PAGE_SIZE.","in":"query","name":"limit","schema":{"format":"int64","minimum":0,"nullable":true,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreStats"}}},"description":"Fleet roll-up across all visible vector stores"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:*:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:*:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:*:read"]}],"summary":"Cross-store stats","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}":{"delete":{"operationId":"deleteVectorStore","parameters":[{"description":"The ID of the vector store to delete.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedObject"}}},"description":"Vector store deleted"},"404":{"description":"Vector store not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:delete","vector_stores:{vector_store_id}:own"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:delete","vector_stores:{vector_store_id}:own"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:delete","vector_stores:{vector_store_id}:own"]}],"summary":"Delete vector store","tags":["knowdb","vector_stores"]},"get":{"operationId":"getVectorStore","parameters":[{"description":"The ID of the vector store to retrieve.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreObject"}}},"description":"Vector store retrieved"},"404":{"description":"Vector store not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"Get vector store","tags":["knowdb","vector_stores"]},"post":{"operationId":"updateVectorStore","parameters":[{"description":"The ID/name of the vector store to modify.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"#379: optional CAS precondition — the store's current `etag`. `*` matches any existing store. A mismatch is refused with 412 and applies nothing; omitting the header is an unconditional merge.","in":"header","name":"If-Match","schema":{"nullable":true,"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"description":"Body for POST /v1/vector_stores/{vector_store_id} (modify). Partial update: `capabilities` fields omitted are left unchanged (RFC 7396 merge onto the stored value); `name` renames the store (#311) while its stable `id` is unchanged. Both are optional — omit to leave unchanged.","properties":{"capabilities":{"description":"Per-VS feature toggles + quotas (issue #8). Every knob is Option\u003cT\u003e — None means \"fall through to the global default\" (operator-set env var).","nullable":true,"properties":{"audio_embeddings_enabled":{"description":"Override the global KNOWDB_ENABLE_AUDIO_EMBEDDINGS for atoms ingested into this store. None falls through.","nullable":true,"type":"boolean"},"chunk_overrides":{"description":"Per-VS chunk-size overrides (#70). Each axis falls through to the global KNOWDB_MIN_CHUNK_SIZE / KNOWDB_MAX_CHUNK_SIZE / KNOWDB_CHUNK_OVERLAP_PERCENT when unset.","nullable":true,"properties":{"max_chunk_size":{"minimum":0,"nullable":true,"type":"integer"},"min_chunk_size":{"minimum":0,"nullable":true,"type":"integer"},"overlap_percent":{"minimum":0,"nullable":true,"type":"integer"}},"type":"object"},"ocr_enabled":{"description":"Override the global KNOWDB_ENABLE_OCR for image content uploaded to this store. None falls through to the global.","nullable":true,"type":"boolean"},"quota":{"nullable":true,"properties":{"max_atoms":{"description":"#396: maximum current-version atoms across all files in this store. Composes with the global KNOWDB_MAX_VS_ATOMS via min() — both apply. None / 0 = unlimited per-VS. Enforced as a next-ingest pre-check.","format":"int64","minimum":0,"nullable":true,"type":"integer"},"max_bytes":{"description":"Maximum total bytes across all content rows in this store. Composes with the global KNOWDB_MAX_VS_BYTES via min() — both apply. None / 0 on this axis = unlimited per-VS; the global ceiling still applies if set.","format":"int64","minimum":0,"nullable":true,"type":"integer"}},"type":"object"},"vision_embeddings_enabled":{"description":"Override the global KNOWDB_ENABLE_VISION_EMBEDDINGS for atoms ingested into this store. None falls through.","nullable":true,"type":"boolean"}},"type":"object"},"name":{"description":"#311: new human name for the store. The stable `id` never changes, so every reference survives the rename. Validated like create (non-empty, not reserved, not id-shaped, not a duplicate).","nullable":true,"type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreObject"}}},"description":"Vector store updated"},"404":{"description":"Vector store not found"},"409":{"description":"Reserved store (e.g. `system`) cannot be modified"},"412":{"description":"`If-Match` precondition failed — the resource changed since the validator was issued. Body carries `current_etag`; nothing was applied."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:configure","vector_stores:{vector_store_id}:manage"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:configure","vector_stores:{vector_store_id}:manage"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:configure","vector_stores:{vector_store_id}:manage"]}],"summary":"Update vector store capabilities/quota (admin/provisioner)","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/files":{"get":{"operationId":"listVectorStoreFiles","parameters":[{"description":"The ID of the vector store to list files for.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"in":"query","name":"after","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"description":"Sort direction: `asc` | `desc` (default `asc`).","in":"query","name":"order","schema":{"description":"Sort direction for list endpoints. Default is `asc`.","enum":["asc","desc"],"nullable":true,"type":"string"}},{"in":"query","name":"prefix","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"purpose","schema":{"nullable":true,"type":"string"}},{"description":"Restrict to a specific vector store (applies only to the /v1/files global list).","in":"query","name":"vector_store_id","schema":{"nullable":true,"type":"string"}},{"description":"Filter by MIME type. Use 'prefix/*' for wildcard family.","in":"query","name":"mime","schema":{"nullable":true,"type":"string"}},{"description":"Filter by IngestCategory (knowdb src/ingest.rs): tabular | text | image | audio | video | code | tools | skills | notebook | spreadsheet | columnar | unknown.","in":"query","name":"category","schema":{"enum":["tabular","text","image","audio","video","code","tools","skills","notebook","spreadsheet","columnar","unknown"],"nullable":true,"type":"string"}},{"description":"Filter by file status. On /v1/vector_stores/{id}/files the accepted values are the OpenAI VectorStoreFile vocabulary: `in_progress` / `completed` / `failed` / `cancelled`. The handler translates these to internal content.status values (which are exposed verbatim on responses via the `phase` field). Issue #36. Quarantined files read as `failed` and are returned by that filter value; use the `phase` field to distinguish them from genuine `error` rows. `fetching` is rejected — use /v1/vector_stores/{id}/stats for in-flight URL-ingest counts.","in":"query","name":"status","schema":{"nullable":true,"type":"string"}},{"description":"Filter by the raw internal lifecycle phase — the SAME vocabulary surfaced on the response `phase` field: pending / text_extracted / chunked / completed / error / quarantined / fetching. Unlike `status` (a coarse OpenAI bucket), `phase` isolates a single state — e.g. phase=quarantined returns ONLY quarantined files. Mutually exclusive with `status`: supplying both is a 400. Unknown values are a 400.","in":"query","name":"phase","schema":{"nullable":true,"type":"string"}},{"description":"ISO 8601 timestamp or Unix seconds; inclusive lower bound on files.created_at.","in":"query","name":"created_after","schema":{"nullable":true,"type":"string"}},{"description":"ISO 8601 timestamp or Unix seconds; exclusive upper bound on files.created_at.","in":"query","name":"created_before","schema":{"nullable":true,"type":"string"}},{"description":"Inclusive lower bound on content.size (bytes).","in":"query","name":"size_min","schema":{"format":"int64","minimum":0,"nullable":true,"type":"integer"}},{"description":"Inclusive upper bound on content.size (bytes).","in":"query","name":"size_max","schema":{"format":"int64","minimum":0,"nullable":true,"type":"integer"}},{"description":"Comma-separated tag list; match files containing at least one.","in":"query","name":"tags_any","schema":{"nullable":true,"type":"string"}},{"description":"Comma-separated tag list; match files containing all.","in":"query","name":"tags_all","schema":{"nullable":true,"type":"string"}},{"description":"Comma-separated tag list; match files containing none.","in":"query","name":"tags_none","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"$ref":"#/components/schemas/VectorStoreFileObject"},"type":"array"},"has_more":{"type":"boolean"},"next_after":{"nullable":true,"type":"string"},"object":{"type":"string"}},"required":["object","data","has_more"],"type":"object"}}},"description":"List of files in the vector store"},"400":{"description":"Invalid query parameters"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"List files in vector store","tags":["knowdb","vector_stores"]},"patch":{"operationId":"mutateVectorStoreFiles","parameters":[{"description":"Vector store name/id (the batch target)","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"description":"#389: batch applied all-or-nothing. Each op is a single-file move/retag (`file_id` XOR `path` + at least one change) or a directory-prefix move (`from_prefix` + `to_prefix`, nothing else).","properties":{"ops":{"items":{"description":"One mutation op. Tag mutation is `tags_set` (full replace) XOR the `tags_add`/`tags_remove` delta.","properties":{"file_id":{"description":"Target a single file by opaque id (XOR `path`).","nullable":true,"type":"string"},"from_prefix":{"description":"Directory-prefix move: match every current file at this prefix or under `prefix/`. Requires `to_prefix`; forbids every other field.","nullable":true,"type":"string"},"if_match":{"description":"Optional CAS precondition — the file's current derived `etag`. A mismatch fails the whole batch with 412.","nullable":true,"type":"string"},"new_path":{"description":"New logical path for a single-file op.","nullable":true,"type":"string"},"path":{"description":"Target a single file by its logical path (XOR `file_id`).","nullable":true,"type":"string"},"tags_add":{"description":"Delta — tags to add (validated). XOR `tags_set`.","items":{"type":"string"},"nullable":true,"type":"array"},"tags_remove":{"description":"Delta — tags to remove (normalized). XOR `tags_set`.","items":{"type":"string"},"nullable":true,"type":"array"},"tags_set":{"description":"Full replacement tag set (validated). XOR the delta fields.","items":{"type":"string"},"nullable":true,"type":"array"},"to_prefix":{"description":"Destination prefix for a `from_prefix` move.","nullable":true,"type":"string"}},"type":"object"},"type":"array"}},"required":["ops"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"description":"#389: emitted only on success — a validation failure short- circuits to an error status with NOTHING written (all-or-nothing).","properties":{"mutated":{"description":"Number of files mutated — equals `results.len()`.","minimum":0,"type":"integer"},"object":{"description":"Always `file_mutation_result`.","type":"string"},"results":{"description":"Per-file outcomes (one per resolved file; prefix moves fanned out).","items":{"description":"One applied mutation's result. `etag` is the file's NEW (post-change) derived etag, suitable as the next `if_match`; `new_path` is set iff the path actually changed.","properties":{"etag":{"type":"string"},"file_id":{"type":"string"},"new_path":{"nullable":true,"type":"string"},"updated_at":{"format":"int64","minimum":0,"type":"integer"}},"required":["file_id","etag","updated_at"],"type":"object"},"type":"array"},"vector_store_id":{"description":"The batch's target store as its stable public id (`vs_\u003chex\u003e` / `system`).","type":"string"}},"required":["object","vector_store_id","mutated","results"],"type":"object"}}},"description":"Batch applied atomically"},"400":{"description":"Malformed batch (bad op combination, invalid path/tag, cap exceeded)"},"404":{"description":"A targeted file/prefix does not resolve in this store"},"409":{"description":"Destination path already exists, or a superseded/non-current version was targeted"},"412":{"description":"An `if_match` precondition failed"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:update","vector_stores:{vector_store_id}:write"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:update","vector_stores:{vector_store_id}:write"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:update","vector_stores:{vector_store_id}:write"]}],"summary":"Transactional batch file mutation (moves/retags + prefix moves)","tags":["knowdb","vector_stores"]},"post":{"operationId":"createVectorStoreFile","parameters":[{"in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"format":"binary","type":"string"},"file_id":{"description":"Target an existing file for `purpose=rename`/`update_metadata`.","nullable":true,"type":"string"},"filename":{"description":"Overrides the `file` part's filename / logical path.","nullable":true,"type":"string"},"mime_type":{"description":"Authoritative client MIME override (knowdb #285).","nullable":true,"type":"string"},"purpose":{"description":"Upload purpose. Also a mode switch: `rename` / `update_metadata` mutate an existing file (require `file_id`) instead of uploading bytes.","type":"string"},"tags":{"description":"Comma-separated tag list applied to the file on upload.","nullable":true,"type":"string"},"vector_store_id":{"description":"Target vector store (id or name). Inert on this scoped route — the {vector_store_id} path segment wins; listed to mirror knowdb's shared CreateOpenAIFileRequest schema (0.15.0).","nullable":true,"type":"string"}},"required":["file","purpose"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreFileObject"}}},"description":"File created and attached. Returns an OpenAIFile object."},"400":{"description":"Malformed multipart body or invalid path"},"404":{"description":"Vector store not found / not permitted"},"413":{"description":"Per-VS quota exceeded"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:create","vector_stores:{vector_store_id}:write"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:create","vector_stores:{vector_store_id}:write"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:create","vector_stores:{vector_store_id}:write"]}],"summary":"Upload + attach a file to a vector store (multipart)","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/files/{file_id}":{"delete":{"operationId":"deleteVectorStoreFile","parameters":[{"description":"The ID of the vector store to remove the file from.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"The ID of the file.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"#379: optional CAS precondition — the vector-store file's current `etag`. `*` matches any existing file. A mismatch is refused with 412 and removes nothing; omitting the header is an unconditional removal.","in":"header","name":"If-Match","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedObject"}}},"description":"File removed from vector store successfully"},"400":{"description":"Malformed `If-Match` header"},"404":{"description":"Vector store file not found"},"412":{"description":"`If-Match` precondition failed — the resource changed since the validator was issued. Body carries `current_etag`; nothing was applied."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:delete","vector_stores:{vector_store_id}:delete"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:delete","vector_stores:{vector_store_id}:delete"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:delete","vector_stores:{vector_store_id}:delete"]}],"summary":"Remove file from vector store","tags":["knowdb","vector_stores"]},"get":{"operationId":"getVectorStoreFile","parameters":[{"description":"The ID of the vector store to associate the file with.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"The ID of the file.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreRetrieveFileObject"}}},"description":"Vector store file retrieved"},"404":{"description":"Vector store file not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"Get file metadata in vector store","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/files/{file_id}/atoms":{"get":{"operationId":"listVectorStoreFileAtoms","parameters":[{"description":"Vector store id/name","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"Opaque file_id","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"Opaque pagination cursor from a previous page's `next_after`.","in":"query","name":"after","schema":{"nullable":true,"type":"string"}},{"description":"Page size (1..=MAX_ATOMS_PER_LIST_PAGE). `0` is rejected.","in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"description":"Atom ordering by `sequence_index`: `asc` (default) or `desc`.","in":"query","name":"order","schema":{"nullable":true,"type":"string"}},{"description":"Include the raw `binary` segment on each atom (default `false`).","in":"query","name":"include_binary","schema":{"nullable":true,"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"description":"One page of a single file's atoms. Mirrors ListFilesResponse.","properties":{"data":{"items":{"$ref":"#/components/schemas/AtomObject"},"type":"array"},"has_more":{"type":"boolean"},"next_after":{"nullable":true,"type":"string"},"object":{"type":"string"}},"required":["object","data","has_more"],"type":"object"}}},"description":"One page of the file's atoms"},"400":{"description":"Invalid cursor or limit"},"404":{"description":"File not found in this vector store"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"List a file's atoms in vector store (sequence order)","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/files/{file_id}/content":{"get":{"operationId":"getVectorStoreFileContent","parameters":[{"description":"The ID of the vector store.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"The ID/URI of the file to retrieve content for.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"Override Content-Disposition: `attachment` (default) | `inline`.","in":"query","name":"disposition","schema":{"description":"Content-Disposition override for file download endpoints. Default is `attachment`.","enum":["attachment","inline"],"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/octet-stream":{"schema":{"items":{"format":"int32","minimum":0,"type":"integer"},"type":"array"}}},"description":"The raw file content"},"404":{"description":"File not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"Stream file content","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/files/{file_id}/extractions":{"get":{"operationId":"listVectorStoreFileExtractions","parameters":[{"in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"in":"path","name":"file_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"description":"The `content.extractions` array produced by the extraction phase; empty for a not-yet-extracted, pure-text-short-circuited, or extraction-less file.","items":{"type":"string"},"type":"array"},"file_id":{"type":"string"},"object":{"type":"string"}},"required":["object","file_id","data"],"type":"object"}}},"description":"The file content's extraction outputs (may be empty)."},"404":{"description":"File not found in this vector store"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"List a VS file content's extraction outputs","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/files/{file_id}/revert":{"post":{"operationId":"revertVectorStoreFile","parameters":[{"description":"The ID of the vector store the file belongs to.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"The ID of the historical version whose content_hash to roll the head back to.","in":"path","name":"file_id","required":true,"schema":{"type":"string"}},{"description":"#379: optional CAS precondition — the file's current `etag`. `*` matches any existing file. A mismatch is refused with 412 and applies nothing; omitting the header is an unconditional revert.","in":"header","name":"If-Match","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreFileObject"}}},"description":"Revert succeeded; the body is the new current version (a fresh file_id at version+1)."},"404":{"description":"File not found or not in this vector store"},"409":{"description":"Revert would be a no-op ({\"error\":\"idempotent_revert\",...} — named version's content already matches head), or named version's content has been garbage-collected ({\"error\":\"content_gc\",...}). See #49."},"412":{"description":"`If-Match` precondition failed — the resource changed since the validator was issued. Body carries `current_etag`; nothing was applied."},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:update","vector_stores:{vector_store_id}:write"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:update","vector_stores:{vector_store_id}:write"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","functions:/api/v1/vector_stores:update","vector_stores:{vector_store_id}:write"]}],"summary":"Revert file to prior version","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/path/content/{uri}":{"get":{"operationId":"retrieveVectorStoreFileByPathContent","parameters":[{"description":"The ID or name of the vector store.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"The file's path (URI) within the store — the trailing path segment(s). Normalised like ingest.","in":"path","name":"uri","required":true,"schema":{"type":"string"}},{"description":"Override Content-Disposition: `attachment` (default) | `inline`.","in":"query","name":"disposition","schema":{"description":"Content-Disposition override for file download endpoints. Default is `attachment`.","enum":["attachment","inline"],"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/octet-stream":{"schema":{"items":{"format":"int32","minimum":0,"type":"integer"},"type":"array"}}},"description":"The raw file content at that path"},"400":{"description":"Invalid path (e.g. contains '..' traversal)"},"404":{"description":"No current file at that path in this store"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"Stream a file's raw content by its logical path (URI) within the store","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/path/metadata/{uri}":{"get":{"operationId":"retrieveVectorStoreFileByPath","parameters":[{"description":"The ID or name of the vector store.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"The file's path (URI) within the store — the trailing path segment(s). Normalised like ingest.","in":"path","name":"uri","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"bytes":{"description":"File size in bytes; 0 until the content row materialises (knowdb #24).","format":"int64","minimum":0,"type":"integer"},"chunk_count":{"format":"int64","minimum":0,"nullable":true,"type":"integer"},"created_at":{"format":"int64","type":"integer"},"etag":{"description":"#347/#389: derived CAS token for PATCH .../files if_match; None when no resolvable file row exists.","nullable":true,"type":"string"},"id":{"type":"string"},"object":{"type":"string"},"phase":{"description":"Raw internal content.status (pending/chunked/completed/error/quarantined/fetching); knowdb #36.","nullable":true,"type":"string"},"status":{"description":"OpenAI VectorStoreFile status: in_progress/completed/failed/cancelled.","type":"string"},"vector_store_id":{"type":"string"}},"required":["id","object","created_at","vector_store_id","bytes","status"],"type":"object"}}},"description":"The current file at that path"},"400":{"description":"Invalid path (e.g. contains '..' traversal)"},"404":{"description":"No current file at that path in this store"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"Get a file's metadata by its logical path (URI) within the store","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/search":{"get":{"operationId":"searchVectorStoreText","parameters":[{"description":"The ID of the vector store to search.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"Query text. Issue #79: must be non-empty / non-whitespace; empty values are rejected with 400 across every mode.","in":"query","name":"query","required":true,"schema":{"type":"string"}},{"in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"in":"query","name":"offset","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"in":"query","name":"max_distance","schema":{"format":"float","nullable":true,"type":"number"}},{"description":"Search mode. `hybrid` (default), `vector`, or `fts`. Issue #80: unknown values are rejected with 400 rather than silently coerced to `hybrid`. (The former `uri` mode was removed — list a file's atoms via `GET /v1/files/{file_id}/atoms` instead.)","in":"query","name":"mode","schema":{"description":"Search mode for /v1/search. Mirrors the MCP search_atoms enum so generated SDKs advertise the same valid set the handler validates.","enum":["hybrid","vector","fts"],"nullable":true,"type":"string"}},{"description":"Vector field a `vector`/`hybrid` query is matched against. One of `text` (default), `vision`, or `audio`.","in":"query","name":"search_field","schema":{"description":"Vector field a `vector`/`hybrid` query is matched against.","enum":["text","vision","audio"],"nullable":true,"type":"string"}},{"description":"Vector store to search. On the scoped GET /v1/vector_stores/{id}/search route the {id} path segment is authoritative and this query param is ignored (#203).","in":"query","name":"vector_store_id","schema":{"nullable":true,"type":"string"}},{"in":"query","name":"include_binary","schema":{"nullable":true,"type":"boolean"}},{"description":"#408: also return atoms belonging to superseded file versions. Default `false`. Superseded versions retain their atoms so `revert` stays a flag flip, but those atoms resolve to no current file and surfaced as hits with null `uri`/`tags`/`file_id`. Set `true` only to search history deliberately. Content is shared, so an atom is excluded only when its `content_hash` is referenced EXCLUSIVELY by superseded versions.","in":"query","name":"include_superseded","schema":{"nullable":true,"type":"boolean"}},{"description":"Comma-separated list of tags that every returned atom must carry (intersection / AND semantics). Mime types are tagged at ingest time with the prefix `mime:`, so `tags=mime:application/pdf` filters to PDFs only.","in":"query","name":"tags","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"atoms":{"items":{"$ref":"#/components/schemas/AtomObject"},"type":"array"},"processing_time_ms":{"format":"int64","minimum":0,"type":"integer"},"status":{"type":"string"},"total_count":{"minimum":0,"nullable":true,"type":"integer"}},"required":["status","atoms","processing_time_ms"],"type":"object"}}},"description":"Successful search"},"400":{"description":"Invalid query parameter (empty `query`, unknown `mode`, or unknown `search_field` value)"},"404":{"description":"Requested vector_store_id not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"VS-scoped text search (query params)","tags":["knowdb","vector_stores","search"]},"post":{"operationId":"searchVectorStore","parameters":[{"description":"The ID of the vector store to search.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"filter":{"description":"Three-way tag predicate accepted in the POST /v1/vector_stores/{id}/search body. Each list is optional; an absent or empty list contributes no constraint. Combined: a hit must satisfy all_of (every tag) AND any_of (at least one) AND none_of (no tag), evaluated against the tags of the atom's source file.","nullable":true,"properties":{"all_of":{"description":"Match only files carrying every one of these tags.","items":{"type":"string"},"nullable":true,"type":"array"},"any_of":{"description":"Match files carrying at least one of these tags.","items":{"type":"string"},"nullable":true,"type":"array"},"none_of":{"description":"Exclude files carrying any of these tags.","items":{"type":"string"},"nullable":true,"type":"array"}},"type":"object"},"include_superseded":{"description":"#408: also return atoms of superseded file versions. Default `false`. Parity with the `include_superseded` query param on `GET /v1/search`. Superseded versions retain their atoms so `revert` stays a flag flip; those atoms resolve to no current file, so excluding them is the default. Content is shared — an atom is excluded only when NO current file references its `content_hash`.","nullable":true,"type":"boolean"},"max_distance":{"description":"Cosine-distance ceiling. Hits whose distance is greater than this are dropped. Defaults to 1.1. Knowdb extension; raise for cross-modal CLAP queries where distances are wider than text/text.","format":"float","nullable":true,"type":"number"},"max_num_results":{"minimum":0,"nullable":true,"type":"integer"},"mode":{"description":"Search mode for /v1/search. Mirrors the MCP search_atoms enum so generated SDKs advertise the same valid set the handler validates.","enum":["hybrid","vector","fts"],"nullable":true,"type":"string"},"offset":{"minimum":0,"nullable":true,"type":"integer"},"query":{"oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]},"search_field":{"description":"Vector field a `vector`/`hybrid` query is matched against.","enum":["text","vision","audio"],"nullable":true,"type":"string"}},"required":["query"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"properties":{"attributes":{},"content":{"items":{"properties":{"text":{"type":"string"},"type":{"type":"string"}},"required":["type","text"],"type":"object"},"type":"array"},"file_id":{"type":"string"},"filename":{"type":"string"},"score":{"format":"float","type":"number"}},"required":["file_id","filename","score","content"],"type":"object"},"type":"array"},"object":{"type":"string"},"search_query":{"items":{"type":"string"},"type":"array"},"total_count":{"minimum":0,"nullable":true,"type":"integer"},"vs_total_count":{"minimum":0,"nullable":true,"type":"integer"}},"required":["object","search_query","data"],"type":"object"}}},"description":"Search results from vector store"},"400":{"description":"Invalid request (unknown search_field, missing query, etc.)"},"500":{"description":"Embedding or vector search failed"},"503":{"description":"Required embedding model not loaded for the requested search_field (operator must check server logs)"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"VS-scoped search (OpenAI/JSON POST shape)","tags":["knowdb","vector_stores","search"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/stats":{"get":{"operationId":"getVectorStoreStats","parameters":[{"description":"Vector store name/id","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"Skip the scan for category/mime_top/tags_top/time_range. Returns materialised counters only. O(1).","in":"query","name":"fast","schema":{"nullable":true,"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VectorStoreStats"}}},"description":"Per-store statistics"},"404":{"description":"Vector store not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"Per-store stats","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/api/v1/vector_stores/{vector_store_id}/tags":{"get":{"operationId":"listVectorStoreTags","parameters":[{"description":"The ID or name of the vector store.","in":"path","name":"vector_store_id","required":true,"schema":{"type":"string"}},{"description":"Opaque pagination cursor from a previous page's `next_after`.","in":"query","name":"after","schema":{"nullable":true,"type":"string"}},{"description":"Page size (1..=100, default 100). `0` is rejected.","in":"query","name":"limit","schema":{"minimum":0,"nullable":true,"type":"integer"}},{"description":"Only return tags starting with this (case-folded) prefix — typeahead for building a tag filter.","in":"query","name":"prefix","schema":{"nullable":true,"type":"string"}},{"description":"Include knowdb's system-injected tags (reserved `x-knowdb-*` + auto-derived `mime:`/`charset:`). Defaults to false.","in":"query","name":"include_reserved","schema":{"nullable":true,"type":"boolean"}},{"description":"#406: comma-separated tags a file must carry every one of to be counted. Same vocabulary/semantics as list_files. When any of tags_all/tags_any/tags_none is present the aggregation runs over only the matching current-version files (per-subset co-occurrence); absent all three, behaviour is the store-wide #346 listing.","in":"query","name":"tags_all","schema":{"nullable":true,"type":"string"}},{"description":"#406: comma-separated tags a file must carry at least one of.","in":"query","name":"tags_any","schema":{"nullable":true,"type":"string"}},{"description":"#406: comma-separated tags a file must carry none of.","in":"query","name":"tags_none","schema":{"nullable":true,"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"properties":{"count":{"format":"int64","minimum":0,"type":"integer"},"tag":{"type":"string"}},"required":["tag","count"],"type":"object"},"type":"array"},"has_more":{"type":"boolean"},"next_after":{"nullable":true,"type":"string"},"object":{"type":"string"},"vector_store_id":{"description":"The store's stable id (`vs_\u003chex\u003e`, knowdb #328).","type":"string"}},"required":["object","vector_store_id","data","has_more"],"type":"object"}}},"description":"The tags in use, with per-tag current-file counts"},"400":{"description":"Invalid pagination cursor or non-positive limit"},"404":{"description":"Vector store not found"},"500":{"description":"Internal server error"}},"security":[{"bearer":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyHeader":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]},{"apiKeyQuery":["functions:/api/v1/vector_stores:read","vector_stores:{vector_store_id}:read"]}],"summary":"List the distinct tags in use in a store, with per-tag current-file counts","tags":["knowdb","vector_stores"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/app":{"description":"HTML page Chat","get":{"description":"Get HTML for Chat","operationId":"page-app-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Chat"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/app:read","users:*:admin"]}],"summary":"Get Chat","tags":["page-app","page"]},"summary":"Page Chat","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/app/-/{path}":{"description":"HTML page Chat (pattern)","get":{"description":"Get HTML for Chat (pattern)","operationId":"page-app-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Chat (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/app:read","users:*:admin"]}],"summary":"Get Chat (pattern)","tags":["page-app","page"]},"summary":"Page Chat (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/audit":{"description":"HTML page Audit","get":{"description":"Get HTML for Audit","operationId":"page-backoffice-audit-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Audit"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/audit:admin","users:*:admin"]}],"summary":"Get Audit","tags":["page-backoffice-audit","page"]},"summary":"Page Audit","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/audit/-/{path}":{"description":"HTML page Audit (pattern)","get":{"description":"Get HTML for Audit (pattern)","operationId":"page-backoffice-audit-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Audit (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/audit:admin","users:*:admin"]}],"summary":"Get Audit (pattern)","tags":["page-backoffice-audit","page"]},"summary":"Page Audit (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/backoffice":{"description":"HTML page Users","get":{"description":"Get HTML for Users","operationId":"page-backoffice-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Users"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice:admin","users:*:admin"]}],"summary":"Get Users","tags":["page-backoffice","page"]},"summary":"Page Users","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/backoffice/-/{path}":{"description":"HTML page Users (pattern)","get":{"description":"Get HTML for Users (pattern)","operationId":"page-backoffice-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Users (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice:admin","users:*:admin"]}],"summary":"Get Users (pattern)","tags":["page-backoffice","page"]},"summary":"Page Users (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/backoffice/contracts":{"description":"HTML page Contracts","get":{"description":"Get HTML for Contracts","operationId":"page-backoffice-contracts-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Contracts"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice/contracts:admin","contracts:*:admin"]}],"summary":"Get Contracts","tags":["page-backoffice-contracts","page"]},"summary":"Page Contracts","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/backoffice/contracts/-/{path}":{"description":"HTML page Contracts (pattern)","get":{"description":"Get HTML for Contracts (pattern)","operationId":"page-backoffice-contracts-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Contracts (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice/contracts:admin","contracts:*:admin"]}],"summary":"Get Contracts (pattern)","tags":["page-backoffice-contracts","page"]},"summary":"Page Contracts (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/billing/v1/config":{"get":{"operationId":"getBillingConfig","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"publishableKey":{"type":"string"}},"required":["publishableKey"],"type":"object"}}},"description":"Publishable configuration"}},"security":[],"summary":"Public billing config (Stripe publishable key)","tags":["billing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/billing/v1/portal-session":{"post":{"operationId":"createPortalSession","requestBody":{"content":{"application/json":{"schema":{"properties":{"return_path":{"maxLength":512,"type":"string"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"url":{"type":"string"}},"required":["url"],"type":"object"}}},"description":"Portal session created"},"400":{"description":"return_path is not a safe same-origin path"},"404":{"description":"Caller owns no store, or the store has no Stripe customer (free tier)"},"409":{"description":"Caller owns more than one billable store — ambiguous until accounts lands (#76)"},"502":{"description":"Stripe rejected the session create"},"503":{"description":"STRIPE_SECRET_KEY or STRIPE_PORTAL_CONFIG_ID unset — fail closed"}},"security":[{"bearer":["functions:/billing/v1:read","users:me:read"]}],"summary":"Create a Stripe Billing Portal session for the caller's subscription","tags":["billing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/billing/v1/setup-intent":{"post":{"operationId":"createSetupIntent","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"maxLength":320,"minLength":3,"type":"string"},"plan":{"enum":["free","launch","scale"],"type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"clientSecret":{"type":"string"},"customerId":{"type":"string"}},"required":["clientSecret"],"type":"object"}}},"description":"SetupIntent created"},"400":{"description":"Invalid email"},"429":{"description":"Rate limited — too many requests"},"502":{"description":"Stripe upstream error"}},"security":[],"summary":"Create a Stripe Customer + SetupIntent for the free-tier signup (public; rate-limited)","tags":["billing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/billing/v1/upgrade":{"post":{"description":"Free -\u003e paid only. Launch \u003c-\u003e Scale is NOT supported here: Stripe cannot\nupdate a multi-product, usage-based subscription, so tier changes on an\nalready-paid store are contact-us for v1 (W9 D1).\n","operationId":"upgradePlan","requestBody":{"content":{"application/json":{"schema":{"properties":{"plan":{"enum":["launch","scale"],"type":"string"}},"required":["plan"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"plan":{"enum":["launch","scale"],"type":"string"},"subscription_id":{"type":"string"}},"required":["plan","subscription_id"],"type":"object"}}},"description":"Subscription active; the store's plan is projected."},"402":{"content":{"application/json":{"schema":{"properties":{"client_secret":{"type":"string"}},"required":["client_secret"],"type":"object"}}},"description":"No saved card. Confirm the returned SetupIntent client_secret, then\nre-POST this operation.\n"},"404":{"description":"The caller owns no store."},"409":{"description":"Already paid, enterprise, ambiguous ownership, or an idempotency-window replay."},"502":{"description":"Stripe unreachable."},"503":{"description":"Billing not configured."}},"security":[{"bearer":["functions:/billing/v1:read","users:me:read"]}],"summary":"Start a paid subscription for the caller's free store.","tags":["billing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/billing/v1/webhook":{"post":{"operationId":"stripeWebhook","parameters":[{"description":"t=\u003cunix\u003e,v1=\u003chmac-sha256 of \"\u003ct\u003e.\u003craw body\u003e\"\u003e","in":"header","name":"Stripe-Signature","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"*/*":{"schema":{"format":"binary","type":"string"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"handled":{"description":"What the handler did (applied|ignored|unmatched)","type":"string"},"received":{"type":"boolean"}},"required":["received"],"type":"object"}}},"description":"Event accepted, or deliberately ignored (unknown type, or an event naming a store we do not own). Ignored events MUST still be 200 — Stripe retries every non-2xx, so a 4xx here would turn a foreign event into a permanent retry storm."},"400":{"description":"Malformed body, or signature verification failed"},"503":{"description":"Signing secret unset — endpoint fails closed rather than accepting unverified events"}},"security":[],"summary":"Stripe subscription lifecycle events (signature-verified; not caller-authenticated)","tags":["billing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/contract":{"description":"HTML page Contract signing","get":{"description":"Get HTML for Contract signing","operationId":"page-contract-signing-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Contract signing"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Get Contract signing","tags":["page-contract-signing","page"]},"summary":"Page Contract signing","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/contracts/v1/contracts":{"get":{"operationId":"listContracts","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"contracts":{"items":{"$ref":"#/components/schemas/ContractSummary"},"type":"array"}},"required":["contracts"],"type":"object"}}},"description":"Contract list"}},"security":[{"bearer":["functions:/contracts/v1:read","contracts:*:admin"]}],"summary":"List contracts, newest first","tags":["contracts"]},"post":{"operationId":"createContract","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractFields"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"id":{"type":"string"},"renderedMarkdown":{"type":"string"},"status":{"type":"string"}},"required":["id","status","renderedMarkdown"],"type":"object"}}},"description":"Draft created"},"400":{"description":"Invalid fields"}},"security":[{"bearer":["functions:/contracts/v1:read","contracts:*:admin"]}],"summary":"Create a contract draft from builder fields (renders the template, computes premium-derived rates)","tags":["contracts"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/contracts/v1/contracts/{id}":{"get":{"operationId":"getContract","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"events":{"items":{"$ref":"#/components/schemas/ContractEvent"},"type":"array"},"fields":{"$ref":"#/components/schemas/ContractFields"},"hostedInvoiceUrl":{"type":"string"},"id":{"type":"string"},"renderedMarkdown":{"type":"string"},"signingUrl":{"type":"string"},"status":{"type":"string"}},"required":["id","status","fields","renderedMarkdown","events"],"type":"object"}}},"description":"Contract detail"},"404":{"description":"Not found"}},"security":[{"bearer":["functions:/contracts/v1:read","contracts:*:admin"]}],"summary":"Contract detail incl. rendered document and audit trail","tags":["contracts"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/contracts/v1/contracts/{id}/send":{"post":{"operationId":"sendContract","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"hostedInvoiceUrl":{"type":"string"},"signingUrl":{"type":"string"},"status":{"type":"string"},"stripeInvoiceId":{"type":"string"}},"required":["status","signingUrl"],"type":"object"}}},"description":"Sent"},"404":{"description":"Not found"},"409":{"description":"Contract is not in a sendable state"},"502":{"description":"Stripe or email upstream error"}},"security":[{"bearer":["functions:/contracts/v1:read","contracts:*:admin"]}],"summary":"Send to the Customer Representative (signing link email + Stripe customer \u0026 first invoice)","tags":["contracts"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/contracts/v1/my":{"get":{"operationId":"listMyContracts","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"contracts":{"items":{"properties":{"customerLegalName":{"type":"string"},"executedAt":{"type":"string"},"hostedInvoiceUrl":{"type":"string"},"id":{"type":"string"},"renderedMarkdown":{"type":"string"},"status":{"type":"string"}},"required":["id","status","customerLegalName","renderedMarkdown"],"type":"object"},"type":"array"}},"required":["contracts"],"type":"object"}}},"description":"The caller's executed contracts (empty list when none)"}},"security":[{"bearer":["functions:/contracts/v1:read"]}],"summary":"Executed contracts belonging to the logged-in representative (self-scoped by email)","tags":["contracts-signing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/contracts/v1/signing/{token}":{"get":{"operationId":"getSigningContract","parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"customerLegalName":{"type":"string"},"customerRepName":{"type":"string"},"hostedInvoiceUrl":{"type":"string"},"loginRequired":{"type":"boolean"},"orderFormAccepted":{"type":"boolean"},"renderedMarkdown":{"type":"string"},"status":{"type":"string"},"termsAccepted":{"type":"boolean"}},"required":["status","renderedMarkdown","customerLegalName","customerRepName","orderFormAccepted","termsAccepted"],"type":"object"}}},"description":"Contract for signing. Access model (#63): the emailed token is the ONLY credential pre-customer — no login. Once the contract is EXECUTED the token stops serving the document: the response carries loginRequired=true with renderedMarkdown empty and no hostedInvoiceUrl, and the rep signs in (their email must match the contract's customer_rep_email) to view it via GET /contracts/v1/my."},"404":{"description":"Unknown or voided token"},"429":{"description":"Rate limited"}},"security":[],"summary":"Fetch the contract for the signing page by capability token (public)","tags":["contracts-signing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/contracts/v1/signing/{token}/accept":{"post":{"operationId":"acceptSigningStep","parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"maxLength":200,"minLength":2,"type":"string"},"step":{"enum":["order_form","terms"],"type":"string"},"title":{"maxLength":200,"minLength":2,"type":"string"}},"required":["step","name","title"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"hostedInvoiceUrl":{"type":"string"},"orderFormAccepted":{"type":"boolean"},"status":{"type":"string"},"termsAccepted":{"type":"boolean"}},"required":["status","orderFormAccepted","termsAccepted"],"type":"object"}}},"description":"Acceptance recorded"},"400":{"description":"Invalid step or out-of-order acceptance"},"404":{"description":"Unknown or voided token"},"409":{"description":"Step already accepted"},"429":{"description":"Rate limited"}},"security":[],"summary":"Record an acceptance step (order_form, then terms) with the signer's identity (public)","tags":["contracts-signing"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/dashboard":{"description":"HTML page nav.dashboard","get":{"description":"Get HTML for nav.dashboard","operationId":"page-dashboard-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.dashboard"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/dashboard:read"]}],"summary":"Get nav.dashboard","tags":["page-dashboard","page"]},"summary":"Page nav.dashboard","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/dashboard/-/{path}":{"description":"HTML page nav.dashboard (pattern)","get":{"description":"Get HTML for nav.dashboard (pattern)","operationId":"page-dashboard-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.dashboard (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/dashboard:read"]}],"summary":"Get nav.dashboard (pattern)","tags":["page-dashboard","page"]},"summary":"Page nav.dashboard (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/developer-keys":{"description":"HTML page nav.devkeys","get":{"description":"Get HTML for nav.devkeys","operationId":"page-developer-keys-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.devkeys"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/developer-keys:read"]}],"summary":"Get nav.devkeys","tags":["page-developer-keys","page"]},"summary":"Page nav.devkeys","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/developer-keys/-/{path}":{"description":"HTML page nav.devkeys (pattern)","get":{"description":"Get HTML for nav.devkeys (pattern)","operationId":"page-developer-keys-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.devkeys (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/developer-keys:read"]}],"summary":"Get nav.devkeys (pattern)","tags":["page-developer-keys","page"]},"summary":"Page nav.devkeys (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/docs":{"description":"HTML page nav.docs","get":{"description":"Get HTML for nav.docs","operationId":"page-docs-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.docs"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/docs:read"]}],"summary":"Get nav.docs","tags":["page-docs","page"]},"summary":"Page nav.docs","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/favicon.ico":{"description":"The favicon SVG resource","get":{"description":"GET the favicon SVG","operationId":"favicon-get","responses":{"200":{"content":{"image/svg+xml":{"schema":{"format":"xml","type":"string"}}},"description":"SVG Favicon"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Favicon SVG","tags":["system","favicon"]},"summary":"Favicon SVG resource","x-kdex-metadata":{"contact":{}},"x-kdex-type":"SYSTEM"},"/feedback/v1/reports":{"post":{"operationId":"submitReport","requestBody":{"content":{"application/json":{"schema":{"properties":{"anonymous":{"type":"boolean"},"email":{"maxLength":320,"nullable":true,"type":"string"},"message":{"maxLength":5000,"minLength":1,"type":"string"},"name":{"maxLength":200,"nullable":true,"type":"string"},"page_url":{"maxLength":2000,"type":"string"},"type":{"enum":["Bug","Idea","Other"],"type":"string"}},"required":["type","message","page_url","anonymous"],"type":"object"}}},"required":true},"responses":{"202":{"description":"Report accepted + emailed"},"400":{"description":"Invalid report (empty message)"},"500":{"description":"Send failed"}},"security":[{"bearer":["functions:/feedback/v1:read","functions:/feedback/v1:create"]}],"summary":"Submit a feedback / bug report (emailed to ops)","tags":["feedback"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/inspector":{"description":"HTML page Inspector","get":{"description":"Get HTML for Inspector","operationId":"page-inspector-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/inspector:read","vector_stores:*:read"]}],"summary":"Get Inspector","tags":["page-inspector","page"]},"summary":"Page Inspector","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/invitations":{"description":"HTML page Invitations","get":{"description":"Get HTML for Invitations","operationId":"page-invitations-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Invitations"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/invitations:admin","users:*:admin"]}],"summary":"Get Invitations","tags":["page-invitations","page"]},"summary":"Page Invitations","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/invitations/-/{path}":{"description":"HTML page Invitations (pattern)","get":{"description":"Get HTML for Invitations (pattern)","operationId":"page-invitations-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Invitations (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/invitations:admin","users:*:admin"]}],"summary":"Get Invitations (pattern)","tags":["page-invitations","page"]},"summary":"Page Invitations (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/invite/v1/requests":{"post":{"operationId":"submitInviteRequest","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"maxLength":320,"minLength":3,"type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"properties":{"status":{"enum":["accepted"],"type":"string"}},"required":["status"],"type":"object"}}},"description":"Invite request accepted + emailed"},"400":{"description":"Invalid email"},"429":{"description":"Rate limited — too many requests"}},"security":[],"summary":"Request an invitation (public; emailed to ops, heavily rate-limited)","tags":["invite"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/manage":{"description":"HTML page nav.manage","get":{"description":"Get HTML for nav.manage","operationId":"admin-memberships-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.manage"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/manage:read"]}],"summary":"Get nav.manage","tags":["admin-memberships","page"]},"summary":"Page nav.manage","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/manage/-/{path}":{"description":"HTML page nav.manage (pattern)","get":{"description":"Get HTML for nav.manage (pattern)","operationId":"admin-memberships-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.manage (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/manage:read"]}],"summary":"Get nav.manage (pattern)","tags":["admin-memberships","page"]},"summary":"Page nav.manage (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/mcp":{"description":"HTML page nav.mcp","get":{"description":"Get HTML for nav.mcp","operationId":"page-mcp-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.mcp"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/mcp:read"]}],"summary":"Get nav.mcp","tags":["page-mcp","page"]},"summary":"Page nav.mcp","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/mcp/-/{path}":{"description":"HTML page nav.mcp (pattern)","get":{"description":"Get HTML for nav.mcp (pattern)","operationId":"page-mcp-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.mcp (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/mcp:read"]}],"summary":"Get nav.mcp (pattern)","tags":["page-mcp","page"]},"summary":"Page nav.mcp (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/pricing":{"description":"HTML page Pricing","get":{"description":"Get HTML for Pricing","operationId":"page-pricing-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Pricing"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/pricing:read"]}],"summary":"Get Pricing","tags":["page-pricing","page"]},"summary":"Page Pricing","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/privacy":{"description":"HTML page Privacy","get":{"description":"Get HTML for Privacy","operationId":"page-privacy-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Privacy"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/privacy:read"]}],"summary":"Get Privacy","tags":["page-privacy","page"]},"summary":"Page Privacy","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/reset-password":{"description":"HTML page Reset password","get":{"description":"Get HTML for Reset password","operationId":"reset-password-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Reset password"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/reset-password:read"]}],"summary":"Get Reset password","tags":["reset-password","page"]},"summary":"Page Reset password","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/reset-password/-/{path}":{"description":"HTML page Reset password (pattern)","get":{"description":"Get HTML for Reset password (pattern)","operationId":"reset-password-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Reset password (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/reset-password:read"]}],"summary":"Get Reset password (pattern)","tags":["reset-password","page"]},"summary":"Page Reset password (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/signup":{"description":"HTML page Sign up","get":{"description":"Get HTML for Sign up","operationId":"signup-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Sign up"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/signup:read"]}],"summary":"Get Sign up","tags":["signup","page"]},"summary":"Page Sign up","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/tenant/v1/admin/knowdb-stores":{"get":{"operationId":"adminListKnowdbStores","responses":{"200":{"content":{"application/json":{"schema":{"items":{"properties":{"atom_count":{"format":"int64","type":"integer"},"capabilities":{"nullable":true,"properties":{"quota":{"nullable":true,"properties":{"max_atoms":{"format":"int64","nullable":true,"type":"integer"},"max_bytes":{"format":"int64","nullable":true,"type":"integer"}},"type":"object"}},"type":"object"},"created_by":{"nullable":true,"type":"string"},"file_count":{"format":"int64","type":"integer"},"id":{"type":"string"},"last_modified_at":{"format":"int64","nullable":true,"type":"integer"},"name":{"nullable":true,"type":"string"},"total_bytes":{"format":"int64","type":"integer"}},"required":["id","total_bytes","file_count","atom_count"],"type":"object"},"type":"array"}}},"description":"OK"},"403":{"description":"Caller is not an admin"},"502":{"description":"The vs-provisioner identity is unconfigured, or knowdb rejected the listing"}},"security":[{"bearer":["functions:/tenant/v1:read","users:*:admin"]}],"summary":"List ALL knowdb vector stores via the vs-provisioner identity (admin only)","tags":["tenant","admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/admin/stores":{"get":{"operationId":"adminListStores","responses":{"200":{"content":{"application/json":{"schema":{"items":{"properties":{"deleted_at":{"format":"date-time","nullable":true,"type":"string"},"display_name":{"nullable":true,"type":"string"},"has_owner_member":{"type":"boolean"},"id":{"type":"string"},"is_canonical":{"type":"boolean"},"member_count":{"format":"int64","type":"integer"},"owner_email":{"nullable":true,"type":"string"},"owner_user_id":{"format":"uuid","type":"string"},"unsubscribed_paid":{"type":"boolean"}},"required":["id","owner_user_id","member_count","is_canonical","has_owner_member","unsubscribed_paid"],"type":"object"},"type":"array"}}},"description":"OK"},"403":{"description":"Caller is not an admin"}},"security":[{"bearer":["functions:/tenant/v1:read","users:*:admin"]}],"summary":"List ALL tenancy stores with a canonical-id flag (admin only)","tags":["tenant","admin"]},"post":{"operationId":"adminCreateStore","requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"maxLength":256,"minLength":1,"type":"string"}},"required":["name"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"id":{"type":"string"}},"required":["id"],"type":"object"}}},"description":"Created — returns the knowdb-assigned canonical store id"},"400":{"description":"Missing or blank name"},"403":{"description":"Caller is not an admin"},"502":{"description":"Provisioner disabled or knowdb create failed"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:create","users:*:admin"]}],"summary":"Create a new knowdb vector store via the vs-provisioner identity (admin only)","tags":["tenant","admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/admin/stores/{id}":{"delete":{"operationId":"deleteStore","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted"},"403":{"description":"Caller is not an admin"},"404":{"description":"No tenancy store with that id"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:update","users:*:admin"]}],"summary":"Hard-delete a tenancy record and its members + invitations (admin only)","tags":["tenant","admin"]},"patch":{"operationId":"adminUpdateStore","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"display_name":{"maxLength":256,"minLength":1,"type":"string"},"quota_atoms":{"format":"int64","minimum":0,"type":"integer"},"quota_bytes":{"format":"int64","minimum":0,"type":"integer"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"display_name":{"nullable":true,"type":"string"},"id":{"type":"string"},"knowdb_synced":{"type":"boolean"},"quota_atoms":{"format":"int64","nullable":true,"type":"integer"},"quota_bytes":{"format":"int64","nullable":true,"type":"integer"}},"required":["id","knowdb_synced"],"type":"object"}}},"description":"Updated"},"400":{"description":"No fields to update, or a blank display name"},"403":{"description":"Caller is not an admin"},"404":{"description":"No live store with that id"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:update","users:*:admin"]}],"summary":"Set a store's display name and/or hard quota, mirroring to knowdb (admin only)","tags":["tenant","admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/admin/stores/{id}/assign":{"post":{"operationId":"assignStoreOwner","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"owner_email":{"type":"string"}},"required":["owner_email"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"created":{"type":"boolean"},"id":{"type":"string"},"owner_user_id":{"format":"uuid","type":"string"}},"required":["id","owner_user_id","created"],"type":"object"}}},"description":"Assigned (created a new tenancy record, or reassigned the owner)"},"400":{"description":"Missing or malformed owner_email"},"403":{"description":"Caller is not an admin"},"404":{"description":"No user with that email"},"409":{"description":"Owner already owns a store (owner-uniqueness constraint)"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:update","users:*:admin"]}],"summary":"Assign a store's owner by email — creates the tenancy record if missing, else reassigns (admin only)","tags":["tenant","admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/admin/stores/{id}/members":{"get":{"operationId":"adminListMembers","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Member"},"type":"array"}}},"description":"OK"},"403":{"description":"Caller is not an admin"}},"security":[{"bearer":["functions:/tenant/v1:read","users:*:admin"]}],"summary":"List a store's members and their roles (admin only)","tags":["tenant","admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/admin/stores/{id}/repoint":{"post":{"operationId":"repointStore","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"canonical_id":{"type":"string"}},"required":["canonical_id"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"canonical_id":{"type":"string"},"id":{"type":"string"}},"required":["id","canonical_id"],"type":"object"}}},"description":"Repointed"},"400":{"description":"Invalid canonical_id (bad shape, or equals the current id)"},"403":{"description":"Caller is not an admin"},"404":{"description":"No tenancy store with that id"},"409":{"description":"Target canonical id already exists"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:update","users:*:admin"]}],"summary":"Re-key a tenancy store id to its canonical knowdb id (admin only)","tags":["tenant","admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/invitations":{"get":{"operationId":"listMyInvitations","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/MyInvitation"},"type":"array"}}},"description":"OK"},"401":{"description":"Unauthorized"}},"security":[{"bearer":["functions:/tenant/v1:read"]}],"summary":"List pending store invitations addressed to the caller (by their email)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/invitations/{invitationId}":{"delete":{"operationId":"declineInvitation","parameters":[{"in":"path","name":"invitationId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Declined"},"404":{"description":"No pending invitation for the caller with that id"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:delete"]}],"summary":"Decline a store invitation addressed to the caller","tags":["tenant"]},"post":{"operationId":"acceptInvitation","parameters":[{"in":"path","name":"invitationId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Accepted — the caller was added to the store"},"404":{"description":"No pending invitation for the caller with that id"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:create"]}],"summary":"Accept a store invitation addressed to the caller (opt-in — adds them to the store with the invited role)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/stores":{"get":{"operationId":"listMyStores","responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Store"},"type":"array"}}},"description":"OK"},"401":{"description":"Unauthorized"}},"security":[{"bearer":["functions:/tenant/v1:read"]}],"summary":"List vector stores the caller owns or is a member of","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/stores/{id}":{"patch":{"operationId":"renameStore","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"display_name":{"maxLength":256,"minLength":1,"type":"string"}},"required":["display_name"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenameResult"}}},"description":"Renamed"},"400":{"description":"Invalid display name"},"403":{"description":"Caller is not the store owner"},"404":{"description":"Store not found"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:update"]}],"summary":"Rename a store's display name (caller must be the store owner)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/stores/{id}/invitations":{"get":{"operationId":"listInvitations","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Invitation"},"type":"array"}}},"description":"OK"},"403":{"description":"Caller lacks a manage role"},"404":{"description":"Store not found"}},"security":[{"bearer":["functions:/tenant/v1:read"]}],"summary":"List pending invitations for a store (caller must have a manage role)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/stores/{id}/invitations/{invitationId}":{"delete":{"operationId":"revokeInvitation","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"invitationId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Revoked"},"403":{"description":"Caller lacks a manage role"},"404":{"description":"Invitation not found"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:delete"]}],"summary":"Revoke a pending invitation (caller must have a manage role)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/stores/{id}/members":{"get":{"operationId":"listMembers","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Member"},"type":"array"}}},"description":"OK"},"403":{"description":"Caller is not a member"},"404":{"description":"Store not found"}},"security":[{"bearer":["functions:/tenant/v1:read"]}],"summary":"List members of a store (caller must be a member)","tags":["tenant"]},"post":{"operationId":"addMember","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"},"role":{"enum":["owner","editor","viewer"],"type":"string"}},"required":["email","role"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddResult"}}},"description":"Existing user added"},"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddResult"}}},"description":"Invitation created for a not-yet user"},"403":{"description":"Caller lacks a manage role on the store"},"404":{"description":"Store not found"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:create"]}],"summary":"Add a member by email (caller must have a manage role)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/stores/{id}/members/{userId}":{"delete":{"operationId":"removeMember","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"userId","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Removed"},"403":{"description":"Caller lacks a manage role, or target is the owner"},"404":{"description":"Store or member not found"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:delete"]}],"summary":"Remove a member (caller must have a manage role; cannot remove the owner)","tags":["tenant"]},"patch":{"operationId":"updateMemberRole","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"path","name":"userId","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"role":{"enum":["owner","editor","viewer"],"type":"string"}},"required":["role"],"type":"object"}}},"required":true},"responses":{"204":{"description":"Role updated"},"403":{"description":"Caller lacks a manage role, or the target is the store owner"},"404":{"description":"Store or member not found"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:update"]}],"summary":"Change a member's role (caller must have a manage role; the store owner's role is fixed)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/tenant/v1/stores/{id}/membership":{"delete":{"operationId":"leaveStore","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Left the store"},"403":{"description":"The store owner cannot leave their own store"},"404":{"description":"The caller is not a member of the store"}},"security":[{"bearer":["functions:/tenant/v1:read","functions:/tenant/v1:delete"]}],"summary":"Leave a store (remove the caller's OWN membership; the owner cannot leave)","tags":["tenant"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/terms":{"description":"HTML page Terms","get":{"description":"Get HTML for Terms","operationId":"page-terms-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Terms"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/terms:read"]}],"summary":"Get Terms","tags":["page-terms","page"]},"summary":"Page Terms","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/tools/bridge-mac":{"description":"HTML page Bridge for Mac","get":{"description":"Get HTML for Bridge for Mac","operationId":"page-bridge-mac-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Bridge for Mac"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/bridge-mac:read"]}],"summary":"Get Bridge for Mac","tags":["page-bridge-mac","page"]},"summary":"Page Bridge for Mac","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/tools/handoff-plugin":{"description":"HTML page Handoff Plugin","get":{"description":"Get HTML for Handoff Plugin","operationId":"page-handoff-plugin-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Handoff Plugin"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/handoff-plugin:read"]}],"summary":"Get Handoff Plugin","tags":["page-handoff-plugin","page"]},"summary":"Page Handoff Plugin","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/tools/inspector-linux":{"description":"HTML page Inspector for Linux","get":{"description":"Get HTML for Inspector for Linux","operationId":"page-inspector-linux-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector for Linux"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/inspector-linux:read"]}],"summary":"Get Inspector for Linux","tags":["page-inspector-linux","page"]},"summary":"Page Inspector for Linux","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/tools/inspector-mac":{"description":"HTML page Inspector for Mac","get":{"description":"Get HTML for Inspector for Mac","operationId":"page-inspector-mac-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector for Mac"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/inspector-mac:read"]}],"summary":"Get Inspector for Mac","tags":["page-inspector-mac","page"]},"summary":"Page Inspector for Mac","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/tools/inspector-widget":{"description":"HTML page Inspector Widget","get":{"description":"Get HTML for Inspector Widget","operationId":"page-inspector-widget-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector Widget"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/inspector-widget:read"]}],"summary":"Get Inspector Widget","tags":["page-inspector-widget","page"]},"summary":"Page Inspector Widget","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/v1/admin/audit":{"get":{"operationId":"listAudit","parameters":[{"description":"Filter to events about this user (audit_log.user_id)","in":"query","name":"user_id","schema":{"format":"uuid","type":"string"}},{"description":"Filter to events on this store (metadata-\u003e\u003e'vector_store_id')","in":"query","name":"vector_store_id","schema":{"type":"string"}},{"description":"Filter to a single event name","in":"query","name":"event","schema":{"type":"string"}},{"description":"Only entries with at \u003e= this instant (RFC3339)","in":"query","name":"from","schema":{"format":"date-time","type":"string"}},{"description":"Only entries with at \u003c this instant (RFC3339)","in":"query","name":"to","schema":{"format":"date-time","type":"string"}},{"in":"query","name":"page","schema":{"default":1,"minimum":1,"type":"integer"}},{"in":"query","name":"size","schema":{"default":20,"maximum":100,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AuditEntry"},"type":"array"},"page":{"type":"integer"},"size":{"type":"integer"},"total":{"type":"integer"},"total_pages":{"type":"integer"}},"required":["items","page","size","total","total_pages"],"type":"object"}}},"description":"Paginated audit entries, newest first"},"400":{"description":"Bad request"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"List audit_log entries, paginated, newest-first, with optional filters","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/audit/events":{"get":{"operationId":"listAuditEvents","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"events":{"items":{"type":"string"},"type":"array"}},"required":["events"],"type":"object"}}},"description":"Distinct event names, ascending"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Distinct event names present in audit_log (for the filter dropdown)","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/invites":{"get":{"description":"Returns only pending invitations (unclaimed, unrevoked, not yet\nexpired). Claimed, revoked, and expired rows are filtered out\nserver-side. A status filter is not exposed in v1.\n","operationId":"listInvites","parameters":[{"description":"1-indexed page number; defaults to 1.","in":"query","name":"page","schema":{"default":1,"minimum":1,"type":"integer"}},{"description":"Page size (rows per page); clamped to [1, 100], defaults to 20.","in":"query","name":"size","schema":{"default":20,"maximum":100,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"properties":{"created_at":{"format":"date-time","type":"string"},"email":{"format":"email","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"invited_by_subject":{"type":"string"}},"required":["id","email","created_at","expires_at","invited_by_subject"],"type":"object"},"type":"array"},"page":{"type":"integer"},"size":{"type":"integer"},"total":{"description":"Count of pending invitations only","type":"integer"},"total_pages":{"type":"integer"}},"required":["items","page","size","total","total_pages"],"type":"object"}}},"description":"Paginated list of pending invitations"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"List pending invitations, paginated","tags":["admin"]},"post":{"operationId":"createInvite","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"},"pre_assigned_claims":{"additionalProperties":true,"description":"jsonb payload merged onto the new user's claims at claim-time","type":"object"},"ttl_days":{"default":14,"description":"Invite TTL in days; defaults to spec §8.4 (14d)","maximum":30,"minimum":1,"type":"integer"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"},"expires_at":{"format":"date-time","type":"string"},"id":{"format":"uuid","type":"string"},"token":{"description":"Raw token; deliver to invitee","type":"string"}},"required":["id","email","token","expires_at"],"type":"object"}}},"description":"Invite created"},"400":{"description":"Validation failed"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"},"409":{"description":"An active invite already exists for this email, or the email belongs to an existing user"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Create an invitation; returns the raw token (v1 dev-mode shortcut)","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/invites/{id}":{"delete":{"description":"Marks an unclaimed invitation as revoked. 404 if the invite\nid doesn't exist or has already been claimed or revoked\n(the partial UPDATE … WHERE claimed_at IS NULL AND\nrevoked_at IS NULL is the natural race arbiter).\n","operationId":"revokeInvite","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Invite revoked"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"},"404":{"description":"No such invite, or already claimed/revoked"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Revoke an unclaimed invitation","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users":{"get":{"operationId":"listUsers","parameters":[{"in":"query","name":"page","schema":{"default":1,"minimum":1,"type":"integer"}},{"in":"query","name":"size","schema":{"default":20,"maximum":100,"minimum":1,"type":"integer"}},{"description":"CSV status filter; default active,disabled,invited","in":"query","name":"status","schema":{"type":"string"}},{"description":"Email-prefix or name-substring","in":"query","name":"q","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/User"},"type":"array"},"page":{"type":"integer"},"size":{"type":"integer"},"total":{"type":"integer"},"total_pages":{"type":"integer"}},"required":["items","page","size","total","total_pages"],"type":"object"}}},"description":"Paginated list of users"},"400":{"description":"Bad request"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"List users, paginated with optional filters","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}":{"get":{"operationId":"getUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"User found"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"},"404":{"description":"No such user"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Fetch a single user by ID","tags":["admin"]},"patch":{"operationId":"patchUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"header","name":"If-Match","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json-patch+json":{"schema":{"items":{"properties":{"op":{"enum":["replace","remove"],"type":"string"},"path":{"type":"string"},"value":{}},"required":["op","path"],"type":"object"},"type":"array"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"User updated"},"400":{"description":"Patch invalid / value rejected"},"401":{"description":"Missing/invalid JWT"},"403":{"description":"Self-target on status/mfa_required"},"404":{"description":"No such user"},"409":{"description":"Illegal state transition"},"412":{"description":"If-Match mismatch"},"415":{"description":"Content-Type must be application/json-patch+json"},"428":{"description":"If-Match required"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Partially update a user via JSON Patch","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/audit":{"get":{"operationId":"getUserAudit","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}},{"in":"query","name":"limit","schema":{"default":20,"maximum":100,"minimum":1,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AuditEntry"},"type":"array"}},"required":["items"],"type":"object"}}},"description":"Audit entries for the user"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Fetch audit log entries for a user","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/force-password-change":{"post":{"operationId":"forcePasswordChange","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"must_change_at set"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"},"404":{"description":"No such user"},"409":{"description":"Illegal state transition"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Force the user to change their password on next login","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/password-reset":{"post":{"operationId":"mintPasswordReset","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"ttl_hours":{"default":24,"maximum":168,"minimum":1,"type":"integer"}},"type":"object"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetMint"}}},"description":"Password-reset token minted"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"},"404":{"description":"No such user"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Mint a password-reset token for a user","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/provision-vs":{"post":{"operationId":"provisionVS","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"quota_atoms":{"format":"int64","type":"integer"},"quota_bytes":{"format":"int64","type":"integer"}},"type":"object"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VSInfo"}}},"description":"Provisioned or already existed"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"},"404":{"description":"No such user"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Idempotently provision the user's owned vector store (shim for pre-existing accounts)","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/purge":{"post":{"operationId":"purgeUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Purged"},"404":{"description":"Not Found"},"409":{"description":"Not purgeable (not tombstoned, or already purged)"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Really-delete a tombstoned user — anonymize + free the email + tear down owned VS"},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/restore":{"post":{"operationId":"restoreUser","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Restored"},"404":{"description":"Not Found"},"409":{"description":"Not restorable (not tombstoned, or already purged)"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Reactivate a tombstoned (status=deleted) user"},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/vs":{"get":{"operationId":"getUserVS","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VSInfo"}}},"description":"The user's owned VS, or status=none if they own none"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Get the user's owned vector store (id + quota), or status=none","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/admin/users/{id}/vs-quota":{"patch":{"operationId":"setVSQuota","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"quota_atoms":{"format":"int64","type":"integer"},"quota_bytes":{"format":"int64","type":"integer"}},"required":["quota_bytes"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VSInfo"}}},"description":"Updated"},"401":{"description":"Missing or invalid JWT"},"403":{"description":"Caller lacks users:*:admin entitlement"},"404":{"description":"User has no owned vector store"}},"security":[{"bearer":["functions:/v1/admin:read","users:*:admin"]}],"summary":"Override the quota on the user's owned vector store","tags":["admin"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/auth/claim-invite":{"post":{"operationId":"claimInvite","requestBody":{"content":{"application/json":{"schema":{"properties":{"family_name":{"type":"string"},"given_name":{"type":"string"},"password":{"minLength":12,"type":"string"},"preferred_language":{"type":"string"},"timezone":{"type":"string"},"token":{"minLength":1,"type":"string"}},"required":["token","password"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"},"id":{"format":"uuid","type":"string"},"status":{"enum":["active"],"type":"string"}},"required":["id","email","status"],"type":"object"}}},"description":"Account created; caller can now /-/login"},"400":{"description":"Validation failed (missing field, weak password, etc.)"},"404":{"description":"Token unknown, expired, revoked, or already claimed"},"409":{"description":"An account with this email already exists (rare race)"}},"security":[],"summary":"Consume an invite token and create the user account","tags":["public"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/auth/forgot-password":{"post":{"operationId":"forgotPassword","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"properties":{"status":{"enum":["accepted"],"type":"string"}},"required":["status"],"type":"object"}}},"description":"Reset link sent (or silently dropped if the email is not registered — anti-enumeration, no leakage between cases)"}},"security":[],"summary":"Email a password-reset link (15-minute TTL) to the caller","tags":["public"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/auth/invite":{"get":{"operationId":"previewInvite","parameters":[{"in":"query","name":"token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"},"expires_at":{"format":"date-time","type":"string"}},"required":["email","expires_at"],"type":"object"}}},"description":"Invite is valid; safe to display claim form"},"404":{"description":"Token unknown, already claimed, expired, or revoked (single status code — anti-enumeration, no leakage between cases)"}},"security":[],"summary":"Return invite metadata (email, expiry) for a raw token","tags":["public"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/auth/reset-password":{"post":{"operationId":"resetPassword","requestBody":{"content":{"application/json":{"schema":{"properties":{"password":{"minLength":12,"type":"string"},"token":{"minLength":1,"type":"string"}},"required":["token","password"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Password updated; caller can now /-/login"},"400":{"description":"Token invalid, expired, or already consumed"}},"security":[],"summary":"Consume a password-reset token and set a new password","tags":["public"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/auth/signup":{"post":{"operationId":"signUp","requestBody":{"content":{"application/json":{"schema":{"properties":{"email":{"format":"email","type":"string"},"plan":{"enum":["free","launch","scale"],"type":"string"},"stripe_customer_id":{"type":"string"}},"required":["email"],"type":"object"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"properties":{"status":{"enum":["accepted"],"type":"string"}},"required":["status"],"type":"object"}}},"description":"Completion email sent (or silently dropped if the email is already registered / already invited — anti-enumeration, no leakage between cases)"},"409":{"content":{"application/json":{"schema":{"properties":{"status":{"enum":["already_authenticated"],"type":"string"}},"required":["status"],"type":"object"}}},"description":"The caller is already authenticated as this address. Returned ONLY\nwhen the request carries a valid session whose identity matches the\nrequested email — an anonymous caller always gets the anti-enum 202,\nbecause enumeration protection exists for exactly that case.\n"}},"security":[{"bearer":["functions:/v1/auth:read"]},{}],"summary":"Self-serve signup — auto-mint an invite and email a completion link","tags":["public"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/chat/completions":{"post":{"operationId":"chatCompletions","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"OK"},"400":{"description":"Bad Request"},"401":{"description":"Unauthorized"},"429":{"description":"Too Many Requests"}},"security":[{"bearer":["functions:/v1/chat:read"]}],"summary":"OpenAI-compatible chat completions (KnowDB-grounded)","tags":["proxy","llm","chat"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/users/apikeys":{"get":{"operationId":"listApiKeys","responses":{"200":{"content":{"application/json":{"schema":{"items":{"properties":{"aud":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","nullable":true,"type":"string"},"id":{"format":"uuid","type":"string"},"jti":{"type":"string"},"name":{"type":"string"},"revoked_at":{"format":"date-time","nullable":true,"type":"string"}},"required":["id","jti","name","aud","created_at"],"type":"object"},"type":"array"}}},"description":"The caller's API keys, newest first"},"401":{"description":"Missing or invalid JWT"}},"security":[{"bearer":["functions:/v1/users:read","users:me:read"]}],"summary":"List the caller's developer API keys (metadata only)","tags":["self-service"]},"post":{"operationId":"createApiKey","requestBody":{"content":{"application/json":{"schema":{"properties":{"aud":{"maxLength":512,"type":"string"},"expires_at":{"format":"date-time","nullable":true,"type":"string"},"id":{"format":"uuid","type":"string"},"jti":{"maxLength":128,"type":"string"},"name":{"maxLength":128,"minLength":1,"type":"string"}},"required":["id","jti","name","aud"],"type":"object"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"aud":{"type":"string"},"created_at":{"format":"date-time","type":"string"},"expires_at":{"format":"date-time","nullable":true,"type":"string"},"id":{"format":"uuid","type":"string"},"jti":{"type":"string"},"name":{"type":"string"},"revoked_at":{"format":"date-time","nullable":true,"type":"string"}},"required":["id","jti","name","aud","created_at"],"type":"object"}}},"description":"Key recorded"},"400":{"description":"Invalid request body"},"401":{"description":"Missing or invalid JWT"}},"security":[{"bearer":["functions:/v1/users:read","users:me:create"]}],"summary":"Record a newly-minted API key's metadata (never the token)","tags":["self-service"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/users/apikeys/{id}":{"delete":{"operationId":"revokeApiKey","parameters":[{"in":"path","name":"id","required":true,"schema":{"format":"uuid","type":"string"}}],"responses":{"204":{"description":"Key marked revoked (idempotent)"},"401":{"description":"Missing or invalid JWT"},"404":{"description":"No such key owned by the caller"}},"security":[{"bearer":["functions:/v1/users:read","users:me:delete"]}],"summary":"Mark one of the caller's API keys revoked (sets revoked_at)","tags":["self-service"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/v1/users/me":{"get":{"operationId":"getMyProfile","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"display_name":{"nullable":true,"type":"string"},"email":{"format":"email","type":"string"},"email_verified_at":{"format":"date-time","nullable":true,"type":"string"},"family_name":{"nullable":true,"type":"string"},"given_name":{"nullable":true,"type":"string"},"id":{"format":"uuid","type":"string"},"mfa_required":{"type":"boolean"},"preferred_language":{"type":"string"},"status":{"enum":["invited","active","disabled","deleted"],"type":"string"},"timezone":{"type":"string"}},"required":["id","email","preferred_language","timezone","status","mfa_required"],"type":"object"}}},"description":"User profile"},"401":{"description":"Missing or invalid JWT"}},"security":[{"bearer":["functions:/v1/users:read","users:me:read"]}],"summary":"Return the authenticated caller's profile","tags":["self-service"]},"patch":{"operationId":"updateMyProfile","requestBody":{"content":{"application/json":{"schema":{"properties":{"display_name":{"maxLength":128,"nullable":true,"type":"string"},"family_name":{"maxLength":128,"nullable":true,"type":"string"},"given_name":{"maxLength":128,"nullable":true,"type":"string"},"preferred_language":{"maxLength":35,"type":"string"},"timezone":{"maxLength":64,"type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"display_name":{"nullable":true,"type":"string"},"email":{"format":"email","type":"string"},"email_verified_at":{"format":"date-time","nullable":true,"type":"string"},"family_name":{"nullable":true,"type":"string"},"given_name":{"nullable":true,"type":"string"},"id":{"format":"uuid","type":"string"},"mfa_required":{"type":"boolean"},"preferred_language":{"type":"string"},"status":{"enum":["invited","active","disabled","deleted"],"type":"string"},"timezone":{"type":"string"}},"required":["id","email","preferred_language","timezone","status","mfa_required"],"type":"object"}}},"description":"Updated profile"},"400":{"description":"Invalid request body"},"401":{"description":"Missing or invalid JWT"}},"security":[{"bearer":["functions:/v1/users:read","users:me:update"]}],"summary":"Update the authenticated caller's editable profile fields","tags":["self-service"]},"x-kdex-metadata":{"contact":{}},"x-kdex-type":"FUNCTION"},"/vector-stores":{"description":"HTML page Vector Stores","get":{"description":"Get HTML for Vector Stores","operationId":"page-backoffice-vector-stores-get","responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Vector Stores"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/vector-stores:admin","users:*:admin"]}],"summary":"Get Vector Stores","tags":["page-backoffice-vector-stores","page"]},"summary":"Page Vector Stores","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/vector-stores/-/{path}":{"description":"HTML page Vector Stores (pattern)","get":{"description":"Get HTML for Vector Stores (pattern)","operationId":"page-backoffice-vector-stores-pattern-get","parameters":[{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Vector Stores (pattern)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/vector-stores:admin","users:*:admin"]}],"summary":"Get Vector Stores (pattern)","tags":["page-backoffice-vector-stores","page"]},"summary":"Page Vector Stores (pattern)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}":{"description":"HTML page Home (localized)","get":{"description":"Get HTML for Home (localized)","operationId":"page-home-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Home (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/:read"]}],"summary":"Get Home (localized)","tags":["page-home","page"]},"summary":"Page Home (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/app":{"description":"HTML page Chat (localized)","get":{"description":"Get HTML for Chat (localized)","operationId":"page-app-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Chat (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/app:read","users:*:admin"]}],"summary":"Get Chat (localized)","tags":["page-app","page"]},"summary":"Page Chat (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/app/-/{path}":{"description":"HTML page Chat (pattern) (localized)","get":{"description":"Get HTML for Chat (pattern) (localized)","operationId":"page-app-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Chat (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/app:read","users:*:admin"]}],"summary":"Get Chat (pattern) (localized)","tags":["page-app","page"]},"summary":"Page Chat (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/audit":{"description":"HTML page Audit (localized)","get":{"description":"Get HTML for Audit (localized)","operationId":"page-backoffice-audit-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Audit (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/audit:admin","users:*:admin"]}],"summary":"Get Audit (localized)","tags":["page-backoffice-audit","page"]},"summary":"Page Audit (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/audit/-/{path}":{"description":"HTML page Audit (pattern) (localized)","get":{"description":"Get HTML for Audit (pattern) (localized)","operationId":"page-backoffice-audit-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Audit (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/audit:admin","users:*:admin"]}],"summary":"Get Audit (pattern) (localized)","tags":["page-backoffice-audit","page"]},"summary":"Page Audit (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/backoffice":{"description":"HTML page Users (localized)","get":{"description":"Get HTML for Users (localized)","operationId":"page-backoffice-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Users (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice:admin","users:*:admin"]}],"summary":"Get Users (localized)","tags":["page-backoffice","page"]},"summary":"Page Users (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/backoffice/-/{path}":{"description":"HTML page Users (pattern) (localized)","get":{"description":"Get HTML for Users (pattern) (localized)","operationId":"page-backoffice-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Users (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice:admin","users:*:admin"]}],"summary":"Get Users (pattern) (localized)","tags":["page-backoffice","page"]},"summary":"Page Users (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/backoffice/contracts":{"description":"HTML page Contracts (localized)","get":{"description":"Get HTML for Contracts (localized)","operationId":"page-backoffice-contracts-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Contracts (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice/contracts:admin","contracts:*:admin"]}],"summary":"Get Contracts (localized)","tags":["page-backoffice-contracts","page"]},"summary":"Page Contracts (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/backoffice/contracts/-/{path}":{"description":"HTML page Contracts (pattern) (localized)","get":{"description":"Get HTML for Contracts (pattern) (localized)","operationId":"page-backoffice-contracts-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Contracts (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/backoffice/contracts:admin","contracts:*:admin"]}],"summary":"Get Contracts (pattern) (localized)","tags":["page-backoffice-contracts","page"]},"summary":"Page Contracts (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/contract":{"description":"HTML page Contract signing (localized)","get":{"description":"Get HTML for Contract signing (localized)","operationId":"page-contract-signing-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Contract signing (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"summary":"Get Contract signing (localized)","tags":["page-contract-signing","page"]},"summary":"Page Contract signing (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/dashboard":{"description":"HTML page nav.dashboard (localized)","get":{"description":"Get HTML for nav.dashboard (localized)","operationId":"page-dashboard-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.dashboard (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/dashboard:read"]}],"summary":"Get nav.dashboard (localized)","tags":["page-dashboard","page"]},"summary":"Page nav.dashboard (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/dashboard/-/{path}":{"description":"HTML page nav.dashboard (pattern) (localized)","get":{"description":"Get HTML for nav.dashboard (pattern) (localized)","operationId":"page-dashboard-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.dashboard (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/dashboard:read"]}],"summary":"Get nav.dashboard (pattern) (localized)","tags":["page-dashboard","page"]},"summary":"Page nav.dashboard (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/developer-keys":{"description":"HTML page nav.devkeys (localized)","get":{"description":"Get HTML for nav.devkeys (localized)","operationId":"page-developer-keys-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.devkeys (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/developer-keys:read"]}],"summary":"Get nav.devkeys (localized)","tags":["page-developer-keys","page"]},"summary":"Page nav.devkeys (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/developer-keys/-/{path}":{"description":"HTML page nav.devkeys (pattern) (localized)","get":{"description":"Get HTML for nav.devkeys (pattern) (localized)","operationId":"page-developer-keys-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.devkeys (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/developer-keys:read"]}],"summary":"Get nav.devkeys (pattern) (localized)","tags":["page-developer-keys","page"]},"summary":"Page nav.devkeys (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/docs":{"description":"HTML page nav.docs (localized)","get":{"description":"Get HTML for nav.docs (localized)","operationId":"page-docs-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.docs (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/docs:read"]}],"summary":"Get nav.docs (localized)","tags":["page-docs","page"]},"summary":"Page nav.docs (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/inspector":{"description":"HTML page Inspector (localized)","get":{"description":"Get HTML for Inspector (localized)","operationId":"page-inspector-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/inspector:read","vector_stores:*:read"]}],"summary":"Get Inspector (localized)","tags":["page-inspector","page"]},"summary":"Page Inspector (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/invitations":{"description":"HTML page Invitations (localized)","get":{"description":"Get HTML for Invitations (localized)","operationId":"page-invitations-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Invitations (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/invitations:admin","users:*:admin"]}],"summary":"Get Invitations (localized)","tags":["page-invitations","page"]},"summary":"Page Invitations (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/invitations/-/{path}":{"description":"HTML page Invitations (pattern) (localized)","get":{"description":"Get HTML for Invitations (pattern) (localized)","operationId":"page-invitations-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Invitations (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/invitations:admin","users:*:admin"]}],"summary":"Get Invitations (pattern) (localized)","tags":["page-invitations","page"]},"summary":"Page Invitations (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/manage":{"description":"HTML page nav.manage (localized)","get":{"description":"Get HTML for nav.manage (localized)","operationId":"admin-memberships-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.manage (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/manage:read"]}],"summary":"Get nav.manage (localized)","tags":["admin-memberships","page"]},"summary":"Page nav.manage (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/manage/-/{path}":{"description":"HTML page nav.manage (pattern) (localized)","get":{"description":"Get HTML for nav.manage (pattern) (localized)","operationId":"admin-memberships-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.manage (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/manage:read"]}],"summary":"Get nav.manage (pattern) (localized)","tags":["admin-memberships","page"]},"summary":"Page nav.manage (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/mcp":{"description":"HTML page nav.mcp (localized)","get":{"description":"Get HTML for nav.mcp (localized)","operationId":"page-mcp-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.mcp (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/mcp:read"]}],"summary":"Get nav.mcp (localized)","tags":["page-mcp","page"]},"summary":"Page nav.mcp (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/mcp/-/{path}":{"description":"HTML page nav.mcp (pattern) (localized)","get":{"description":"Get HTML for nav.mcp (pattern) (localized)","operationId":"page-mcp-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for nav.mcp (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/mcp:read"]}],"summary":"Get nav.mcp (pattern) (localized)","tags":["page-mcp","page"]},"summary":"Page nav.mcp (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/pricing":{"description":"HTML page Pricing (localized)","get":{"description":"Get HTML for Pricing (localized)","operationId":"page-pricing-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Pricing (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/pricing:read"]}],"summary":"Get Pricing (localized)","tags":["page-pricing","page"]},"summary":"Page Pricing (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/privacy":{"description":"HTML page Privacy (localized)","get":{"description":"Get HTML for Privacy (localized)","operationId":"page-privacy-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Privacy (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/privacy:read"]}],"summary":"Get Privacy (localized)","tags":["page-privacy","page"]},"summary":"Page Privacy (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/reset-password":{"description":"HTML page Reset password (localized)","get":{"description":"Get HTML for Reset password (localized)","operationId":"reset-password-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Reset password (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/reset-password:read"]}],"summary":"Get Reset password (localized)","tags":["reset-password","page"]},"summary":"Page Reset password (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/reset-password/-/{path}":{"description":"HTML page Reset password (pattern) (localized)","get":{"description":"Get HTML for Reset password (pattern) (localized)","operationId":"reset-password-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Reset password (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/reset-password:read"]}],"summary":"Get Reset password (pattern) (localized)","tags":["reset-password","page"]},"summary":"Page Reset password (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/signup":{"description":"HTML page Sign up (localized)","get":{"description":"Get HTML for Sign up (localized)","operationId":"signup-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Sign up (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/signup:read"]}],"summary":"Get Sign up (localized)","tags":["signup","page"]},"summary":"Page Sign up (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/terms":{"description":"HTML page Terms (localized)","get":{"description":"Get HTML for Terms (localized)","operationId":"page-terms-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Terms (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/terms:read"]}],"summary":"Get Terms (localized)","tags":["page-terms","page"]},"summary":"Page Terms (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/tools/bridge-mac":{"description":"HTML page Bridge for Mac (localized)","get":{"description":"Get HTML for Bridge for Mac (localized)","operationId":"page-bridge-mac-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Bridge for Mac (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/bridge-mac:read"]}],"summary":"Get Bridge for Mac (localized)","tags":["page-bridge-mac","page"]},"summary":"Page Bridge for Mac (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/tools/handoff-plugin":{"description":"HTML page Handoff Plugin (localized)","get":{"description":"Get HTML for Handoff Plugin (localized)","operationId":"page-handoff-plugin-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Handoff Plugin (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/handoff-plugin:read"]}],"summary":"Get Handoff Plugin (localized)","tags":["page-handoff-plugin","page"]},"summary":"Page Handoff Plugin (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/tools/inspector-linux":{"description":"HTML page Inspector for Linux (localized)","get":{"description":"Get HTML for Inspector for Linux (localized)","operationId":"page-inspector-linux-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector for Linux (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/inspector-linux:read"]}],"summary":"Get Inspector for Linux (localized)","tags":["page-inspector-linux","page"]},"summary":"Page Inspector for Linux (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/tools/inspector-mac":{"description":"HTML page Inspector for Mac (localized)","get":{"description":"Get HTML for Inspector for Mac (localized)","operationId":"page-inspector-mac-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector for Mac (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/inspector-mac:read"]}],"summary":"Get Inspector for Mac (localized)","tags":["page-inspector-mac","page"]},"summary":"Page Inspector for Mac (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/tools/inspector-widget":{"description":"HTML page Inspector Widget (localized)","get":{"description":"Get HTML for Inspector Widget (localized)","operationId":"page-inspector-widget-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Inspector Widget (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/tools/inspector-widget:read"]}],"summary":"Get Inspector Widget (localized)","tags":["page-inspector-widget","page"]},"summary":"Page Inspector Widget (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/vector-stores":{"description":"HTML page Vector Stores (localized)","get":{"description":"Get HTML for Vector Stores (localized)","operationId":"page-backoffice-vector-stores-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Vector Stores (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/vector-stores:admin","users:*:admin"]}],"summary":"Get Vector Stores (localized)","tags":["page-backoffice-vector-stores","page"]},"summary":"Page Vector Stores (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"},"/{l10n}/vector-stores/-/{path}":{"description":"HTML page Vector Stores (pattern) (localized)","get":{"description":"Get HTML for Vector Stores (pattern) (localized)","operationId":"page-backoffice-vector-stores-pattern-localized-get","parameters":[{"description":"Path parameter: l10n","in":"path","name":"l10n","required":true,"schema":{"type":"string"}},{"allowReserved":true,"description":"Wildcard path parameter: path (captures remaining path segments)","in":"path","name":"path","required":true,"schema":{"description":"May contain multiple path segments separated by slashes","type":"string"}}],"responses":{"200":{"content":{"text/html":{"schema":{"format":"html","type":"string"}}},"description":"HTML for Vector Stores (pattern) (localized)"},"303":{"$ref":"#/components/responses/SeeOther"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"bearer":["pages:/vector-stores:admin","users:*:admin"]}],"summary":"Get Vector Stores (pattern) (localized)","tags":["page-backoffice-vector-stores","page"]},"summary":"Page Vector Stores (pattern) (localized)","x-kdex-metadata":{"contact":{}},"x-kdex-type":"PAGE"}},"security":[{"apiKeyCookie":[]},{"apiKeyHeader":[]},{"apiKeyQuery":[]},{"bearer":[]},{"oauth2":[]},{"oidc":[]},{}],"servers":[{"url":"http://dev.knowdrive.ai"}],"tags":[{"name":"system"},{"name":"apitoken"},{"name":"auth"},{"name":"login"},{"name":"logout"},{"name":"backend"},{"name":"navigation"},{"name":"oauth2"},{"name":"openapi"},{"name":"jsonschema"},{"name":"schema"},{"name":"state"},{"name":"translation"},{"name":"localization"},{"name":"jwks"},{"name":"jwt"},{"name":"oidc"},{"name":"knowdb"},{"name":"events"},{"name":"files"},{"name":"ingest"},{"name":"mcp"},{"name":"search"},{"name":"uploads"},{"name":"vector_stores"},{"name":"page-app"},{"name":"page"},{"name":"page-backoffice-audit"},{"name":"page-backoffice"},{"name":"page-backoffice-contracts"},{"name":"billing"},{"name":"page-contract-signing"},{"name":"contracts-signing"},{"name":"contracts"},{"name":"page-dashboard"},{"name":"page-developer-keys"},{"name":"page-docs"},{"name":"favicon"},{"name":"feedback"},{"name":"page-inspector"},{"name":"page-invitations"},{"name":"invite"},{"name":"admin-memberships"},{"name":"page-mcp"},{"name":"page-pricing"},{"name":"page-privacy"},{"name":"reset-password"},{"name":"signup"},{"name":"tenant"},{"name":"admin"},{"name":"page-terms"},{"name":"page-bridge-mac"},{"name":"page-handoff-plugin"},{"name":"page-inspector-linux"},{"name":"page-inspector-mac"},{"name":"page-inspector-widget"},{"name":"public"},{"name":"proxy"},{"name":"llm"},{"name":"chat"},{"name":"self-service"},{"name":"page-backoffice-vector-stores"},{"name":"page-home"}]}