openapi: 3.2.0 info: title: Vaquill Ai Facts API version: 1.0.0 description: 'Operations tagged Facts across 2 of this provider''s published API definitions: vaquill-ai-workspace-openapi.json, vaquill-ai-workspace-openapi.yml. Each path carries the servers of the definition it was published in.' servers: - url: https://api.vaquill.ai/workspace description: Vaquill Legal Workspace API (production) - url: /workspace description: Vaquill Legal Workspace API (relative to the mount) security: - WorkspaceAuth: [] tags: - name: Facts description: 'The cross-document fact ledger for a matter: what every document in it asserts, coalesced and cited back to its source passages.' paths: /v1/matters/{matterId}/fact-sets: get: tags: - Facts summary: List fact sets in a matter description: 'Every fact set generated for this matter, newest request first. The first row is the most recent ATTEMPT, which is not necessarily the one in force: a failed generation leaves the previous set untouched. `isCurrent` is what says which set the product itself would show, and it is how you find the ledger to read. Generating a new set never edits an old one. The previous set and its facts stay readable at their own ids; they simply stop being current.' operationId: factSets.list parameters: - name: matterId in: path required: true schema: type: string title: Matterid description: '`mat_` identifier of the matter to work inside. Everything in this API hangs off a matter, and the matter in the path is what the authorization boundary is checked against. Take it from `GET /v1/matters`.' - name: limit in: query required: false schema: type: integer maximum: 200 minimum: 1 description: How many rows to return, 1 to 200. Defaults to 50. default: 50 title: Limit description: How many rows to return, 1 to 200. Defaults to 50. - name: offset in: query required: false schema: type: integer minimum: 0 description: 'How many rows to skip before returning any. Combine with `limit` to page: `offset=0`, then `offset=50`, and so on. Offsets are positional, not stable, so a set that changes while you page can show a row twice or not at all.' default: 0 title: Offset description: 'How many rows to skip before returning any. Combine with `limit` to page: `offset=0`, then `offset=50`, and so on. Offsets are positional, not stable, so a set that changes while you page can show a row twice or not at all.' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/Page_FactSet_' example: data: - id: fct_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 matterId: mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 status: succeeded mode: standard isCurrent: false isStale: false changedDocCount: 1 coverage: included: 1 total: 128 excluded: 1 factCount: 1 conflictCount: 1 createdAt: '2026-08-19T14:32:10Z' completedAt: '2026-08-19T14:32:10Z' pagination: limit: 50 offset: 0 total: 128 hasMore: false '422': description: The request does not match the published schema. `errors` names each rejected field and why. The submitted value is never echoed back. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/ValidationProblem' '401': description: The credential is missing, malformed, unknown, revoked or expired. `type` is `invalid-credential`, or `wrong-product-credential` when a `vq_key_` Data API key was sent to this API. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '403': description: The credential does not carry a scope this operation requires (`insufficient-scope`), or the organization's installation is suspended (`installation-inactive`). headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '404': description: The resource does not exist, is not this organization's, or is outside this installation's matter allowlist. The three are deliberately indistinguishable, so the status code cannot be used to discover which ids exist in another organization. Each resource has its own `type`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '429': description: Too many requests for this credential's tier. Honour `Retry-After`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 Retry-After: description: Seconds to wait before retrying. schema: type: integer content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '500': description: An unexpected error on our side. The body carries a stable `type` and the request id and nothing else; the cause is in our logs. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '503': description: A dependency this request needs is unavailable, so nothing was done. Retryable. Authentication fails closed rather than admitting the request, so this is never a statement about your credential. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' post: tags: - Facts summary: Generate a fact set description: 'Build a fact ledger for the matter. 202 with an operation to poll. Two callers asking for the same matter at once do NOT start two runs: the second attaches to the first and both operations poll the same set to the same terminal status. That is separate from `Idempotency-Key`, which makes ONE caller''s retry free. 409 when the matter holds no finished documents, 429 when too many generations are already in flight, 503 when the guard deciding that cannot be reached. None of the three writes anything, so a refused run is free. **A regeneration resets attorney review.** `userStatus` on a fact is per fact and per set, so a lawyer who confirmed forty facts yesterday sees forty unreviewed facts after the next run. Nightly regeneration is therefore a decision, not a default.' operationId: factSets.generate parameters: - name: matterId in: path required: true schema: type: string title: Matterid description: '`mat_` identifier of the matter to work inside. Everything in this API hangs off a matter, and the matter in the path is what the authorization boundary is checked against. Take it from `GET /v1/matters`.' - name: Idempotency-Key in: header required: false schema: anyOf: - type: string - type: 'null' title: Idempotency-Key description: A unique value of your choosing, so a retried launch returns the FIRST operation instead of starting a second billable job. Reusing one with a different body is refused. Retrying with the same key and the same body is free and is the intended way to recover from a timeout. requestBody: content: application/json: schema: anyOf: - $ref: '#/components/schemas/FactSetGenerateRequest' - type: 'null' title: Body example: mode: standard responses: '202': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/Operation' example: id: op_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 type: matrix.run status: succeeded createdAt: '2026-08-19T14:32:10Z' completedAt: '2026-08-19T14:32:10Z' matterId: mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 resource: kind: matrix id: mtx_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 url: https://storage.vaquill.ai/exports/msa-acme-v3-redline.docx?signature=... progress: done: 24 total: 128 unit: cells requestId: req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 '422': description: The request does not match the published schema. `errors` names each rejected field and why. The submitted value is never echoed back. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/ValidationProblem' '401': description: The credential is missing, malformed, unknown, revoked or expired. `type` is `invalid-credential`, or `wrong-product-credential` when a `vq_key_` Data API key was sent to this API. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '403': description: The credential does not carry a scope this operation requires (`insufficient-scope`), or the organization's installation is suspended (`installation-inactive`). headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '404': description: The resource does not exist, is not this organization's, or is outside this installation's matter allowlist. The three are deliberately indistinguishable, so the status code cannot be used to discover which ids exist in another organization. Each resource has its own `type`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '429': description: Too many requests for this credential's tier. Honour `Retry-After`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 Retry-After: description: Seconds to wait before retrying. schema: type: integer content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '500': description: An unexpected error on our side. The body carries a stable `type` and the request id and nothing else; the cause is in our logs. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '503': description: A dependency this request needs is unavailable, so nothing was done. Retryable. Authentication fails closed rather than admitting the request, so this is never a statement about your credential. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' servers: - url: https://api.vaquill.ai/workspace description: Vaquill Legal Workspace API (production) - url: /workspace description: Vaquill Legal Workspace API (relative to the mount) /v1/matters/{matterId}/fact-sets/{factSetId}: get: tags: - Facts summary: Get a fact set description: 'One fact set''s header: status, coverage and staleness. Facts are a separate read. `coverage` is the field to read before trusting a ledger as complete. The reducer extracts at most 60 documents inline, so on a larger matter `coverage.excluded` is non-zero and the operation still reports 100 percent: it IS complete, for what it read, and this is the only place that says what that was. `isStale` is computed per request against the matter''s documents as they are now, never stored. A `404` covers every reason the set is not readable: no such id, another organization''s, another matter''s, or a matter that has never generated one.' operationId: factSets.get parameters: - name: matterId in: path required: true schema: type: string title: Matterid description: '`mat_` identifier of the matter to work inside. Everything in this API hangs off a matter, and the matter in the path is what the authorization boundary is checked against. Take it from `GET /v1/matters`.' - name: factSetId in: path required: true schema: type: string title: Factsetid description: '`fct_` identifier of the fact set. Returned on the operation that generated it.' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FactSet' example: id: fct_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 matterId: mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 status: succeeded mode: standard isCurrent: false isStale: false changedDocCount: 1 coverage: included: 1 total: 128 excluded: 1 factCount: 1 conflictCount: 1 createdAt: '2026-08-19T14:32:10Z' completedAt: '2026-08-19T14:32:10Z' '422': description: The request does not match the published schema. `errors` names each rejected field and why. The submitted value is never echoed back. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/ValidationProblem' '401': description: The credential is missing, malformed, unknown, revoked or expired. `type` is `invalid-credential`, or `wrong-product-credential` when a `vq_key_` Data API key was sent to this API. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '403': description: The credential does not carry a scope this operation requires (`insufficient-scope`), or the organization's installation is suspended (`installation-inactive`). headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '404': description: The resource does not exist, is not this organization's, or is outside this installation's matter allowlist. The three are deliberately indistinguishable, so the status code cannot be used to discover which ids exist in another organization. Each resource has its own `type`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '429': description: Too many requests for this credential's tier. Honour `Retry-After`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 Retry-After: description: Seconds to wait before retrying. schema: type: integer content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '500': description: An unexpected error on our side. The body carries a stable `type` and the request id and nothing else; the cause is in our logs. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '503': description: A dependency this request needs is unavailable, so nothing was done. Retryable. Authentication fails closed rather than admitting the request, so this is never a statement about your credential. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' servers: - url: https://api.vaquill.ai/workspace description: Vaquill Legal Workspace API (production) - url: /workspace description: Vaquill Legal Workspace API (relative to the mount) /v1/matters/{matterId}/fact-sets/{factSetId}/facts: get: tags: - Facts summary: List the facts in a set description: 'The facts in one set, in the reducer''s reading order. Ordered by `position` ascending, which is section-clustered and then date ascending WITHIN a section. It is a reading order, not a chronology; for a chronology use the chronology routes. Each fact ships with every passage behind it. **Resolve a citation by finding its `quote` in the document''s text**, not by any offset: no offset is published, because the ones we store index a string this API does not serve. A citation whose `sourceAvailable` is false points at a document that has since been removed; its quote is a snapshot and stays accurate.' operationId: factSets.facts parameters: - name: matterId in: path required: true schema: type: string title: Matterid description: '`mat_` identifier of the matter to work inside. Everything in this API hangs off a matter, and the matter in the path is what the authorization boundary is checked against. Take it from `GET /v1/matters`.' - name: factSetId in: path required: true schema: type: string title: Factsetid description: '`fct_` identifier of the fact set. Returned on the operation that generated it.' - name: limit in: query required: false schema: type: integer maximum: 200 minimum: 1 description: How many rows to return, 1 to 200. Defaults to 50. default: 50 title: Limit description: How many rows to return, 1 to 200. Defaults to 50. - name: offset in: query required: false schema: type: integer minimum: 0 description: 'How many rows to skip before returning any. Combine with `limit` to page: `offset=0`, then `offset=50`, and so on. Offsets are positional, not stable, so a set that changes while you page can show a row twice or not at all.' default: 0 title: Offset description: 'How many rows to skip before returning any. Combine with `limit` to page: `offset=0`, then `offset=50`, and so on. Offsets are positional, not stable, so a set that changes while you page can show a row twice or not at all.' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/Page_Fact_' example: data: - id: fac_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 section: obligation factType: obligation canonicalText: The Supplier's total liability under the Master Services Agreement is capped at the fees paid in the preceding twelve months. shortLabel: value explanation: value eventDate: '2026-08-19' eventDateEnd: '2026-08-19' amountValue: 1.0 amountCurrency: value issueLabel: value entities: - value citations: - documentId: doc_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 documentName: value quote: in no event shall either party be liable for indirect damages pageStart: 1 pageEnd: 1 citationRole: primary sourceAvailable: false confidence: 0.92 supportCount: 1 contradictionCount: 1 isConflicted: false position: 0 pagination: limit: 50 offset: 0 total: 128 hasMore: false '422': description: The request does not match the published schema. `errors` names each rejected field and why. The submitted value is never echoed back. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/ValidationProblem' '401': description: The credential is missing, malformed, unknown, revoked or expired. `type` is `invalid-credential`, or `wrong-product-credential` when a `vq_key_` Data API key was sent to this API. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '403': description: The credential does not carry a scope this operation requires (`insufficient-scope`), or the organization's installation is suspended (`installation-inactive`). headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '404': description: The resource does not exist, is not this organization's, or is outside this installation's matter allowlist. The three are deliberately indistinguishable, so the status code cannot be used to discover which ids exist in another organization. Each resource has its own `type`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '429': description: Too many requests for this credential's tier. Honour `Retry-After`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 Retry-After: description: Seconds to wait before retrying. schema: type: integer content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '500': description: An unexpected error on our side. The body carries a stable `type` and the request id and nothing else; the cause is in our logs. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '503': description: A dependency this request needs is unavailable, so nothing was done. Retryable. Authentication fails closed rather than admitting the request, so this is never a statement about your credential. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' servers: - url: https://api.vaquill.ai/workspace description: Vaquill Legal Workspace API (production) - url: /workspace description: Vaquill Legal Workspace API (relative to the mount) /v1/matters/{matterId}/fact-sets/{factSetId}/exports: post: tags: - Facts summary: Export a fact set as CSV, PDF or DOCX description: 'Render the whole ledger to CSV, PDF or DOCX and return the bytes. A POST rather than a GET because it produces something that did not exist: the file is rendered per call rather than fetched, and recording that as a creation is what lets an audit answer who took a copy and when. The whole set, never a page of it. Over the inline ceiling this answers 413 rather than sending a partial file, because a truncated ledger a customer believes is complete is worse than a refusal.' operationId: factSets.export parameters: - name: matterId in: path required: true schema: type: string title: Matterid description: '`mat_` identifier of the matter to work inside. Everything in this API hangs off a matter, and the matter in the path is what the authorization boundary is checked against. Take it from `GET /v1/matters`.' - name: factSetId in: path required: true schema: type: string title: Factsetid description: '`fct_` identifier of the fact set. Returned on the operation that generated it.' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FactSetExportRequest' example: format: csv responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FactSetExport' example: format: docx filename: msa-acme-v3.docx sizeBytes: 248193 content: UEsDBBQABgAIAAAAIQ... factCount: 1 '422': description: The request does not match the published schema. `errors` names each rejected field and why. The submitted value is never echoed back. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/ValidationProblem' '401': description: The credential is missing, malformed, unknown, revoked or expired. `type` is `invalid-credential`, or `wrong-product-credential` when a `vq_key_` Data API key was sent to this API. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '403': description: The credential does not carry a scope this operation requires (`insufficient-scope`), or the organization's installation is suspended (`installation-inactive`). headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 WWW-Authenticate: description: RFC 9110 authentication challenge. schema: type: string content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '404': description: The resource does not exist, is not this organization's, or is outside this installation's matter allowlist. The three are deliberately indistinguishable, so the status code cannot be used to discover which ids exist in another organization. Each resource has its own `type`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '429': description: Too many requests for this credential's tier. Honour `Retry-After`. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 Retry-After: description: Seconds to wait before retrying. schema: type: integer content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '500': description: An unexpected error on our side. The body carries a stable `type` and the request id and nothing else; the cause is in our logs. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' '503': description: A dependency this request needs is unavailable, so nothing was done. Retryable. Authentication fails closed rather than admitting the request, so this is never a statement about your credential. headers: X-Request-ID: description: The id of this request. The same value appears as `requestId` in the body. Quote it when contacting support. schema: type: string examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 content: application/problem+json: schema: $ref: '#/components/schemas/Problem' servers: - url: https://api.vaquill.ai/workspace description: Vaquill Legal Workspace API (production) - url: /workspace description: Vaquill Legal Workspace API (relative to the mount) components: schemas: Page_Fact_: properties: data: items: $ref: '#/components/schemas/Fact' type: array title: Data description: The rows in this window, in the collection's default order. pagination: $ref: '#/components/schemas/Pagination' description: Where this window sits in the full result set. additionalProperties: false type: object required: - data - pagination title: Page[Fact] OperationStatus: type: string enum: - queued - running - succeeded - failed - cancelled title: OperationStatus description: 'The public five. There is no sixth, and there are no synonyms. Internal vocabularies spell terminal success `completed`, `ready`, `extracted`, `succeeded` and `fresh`; terminal failure `failed` and `error`; queued `pending`, `queued` and `draft`. All of that is collapsed here by `app.workspace_api.adapters.status_map`, which refuses to guess.' FactSetExportRequest: properties: format: type: string enum: - csv - pdf - docx title: Format description: '`csv` for a spreadsheet, `pdf` or `docx` for a document.' examples: - csv additionalProperties: false type: object required: - format title: FactSetExportRequest Fact: properties: id: type: string title: Id description: '`fac_` identifier, stable for the life of this fact set.' examples: - fac_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 section: type: string title: Section description: 'Which part of the ledger this fact was clustered into, for example `key_fact`, `party` or `chronology`. Publisher-controlled and open: read it, do not switch on an exhaustive list of it.' examples: - obligation factType: type: string title: Facttype description: What kind of statement this is, for example `party`, `date`, `amount` or `obligation`. Open, for the same reason as `section`. examples: - obligation canonicalText: type: string title: Canonicaltext description: The fact as one sentence, merged across its sources. examples: - The Supplier's total liability under the Master Services Agreement is capped at the fees paid in the preceding twelve months. shortLabel: anyOf: - type: string - type: 'null' title: Shortlabel description: A compact label for a table cell. examples: - Liability cap explanation: anyOf: - type: string - type: 'null' title: Explanation description: Rarely populated; the reducer leaves it empty by design. examples: - The cap is stated in clause 8.2 and is not repeated in the order form. eventDate: anyOf: - type: string format: date - type: 'null' title: Eventdate description: The date this fact is about, when it has one. examples: - '2026-08-19' eventDateEnd: anyOf: - type: string format: date - type: 'null' title: Eventdateend description: The end of a date range, when the fact spans one. examples: - '2026-08-19' amountValue: anyOf: - type: number - type: 'null' title: Amountvalue description: The monetary amount, when the fact carries one. examples: - 1.0 amountCurrency: anyOf: - type: string - type: 'null' title: Amountcurrency description: ISO code for `amountValue`. examples: - USD issueLabel: anyOf: - type: string - type: 'null' title: Issuelabel description: The issue this fact bears on. examples: - Limitation of liability entities: items: type: string type: array title: Entities description: Party and entity names named by this fact. examples: - - value citations: items: $ref: '#/components/schemas/FactCitation' type: array title: Citations description: Every passage behind the fact, `primary` first. Never empty on a generated fact. confidence: anyOf: - type: number - type: 'null' title: Confidence description: 0 to 1, the strongest supporting passage's confidence. examples: - 0.92 supportCount: type: integer title: Supportcount description: How many passages support this fact. examples: - 1 contradictionCount: type: integer title: Contradictioncount description: How many rival statements of the same thing were found in the matter. examples: - 1 isConflicted: type: boolean title: Isconflicted description: True when the matter's documents state this fact more than one way. The rival statements are separate facts; this flags that they exist. examples: - false position: type: integer title: Position description: 'Ordering within the set: section first, then dated facts ascending, then the best-supported. It is a reading order, not a chronology.' examples: - 0 additionalProperties: false type: object required: - id - section - factType - canonicalText - supportCount - contradictionCount - isConflicted - position title: Fact description: One clustered statement, with every passage that supports it. FactCitation: properties: documentId: anyOf: - type: string - type: 'null' title: Documentid description: The `doc_` document this passage came from, or null when the citation predates a document that has since been deleted. examples: - doc_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 documentName: anyOf: - type: string - type: 'null' title: Documentname description: The document's filename at the moment the set was generated. examples: - msa-acme-v3.docx quote: anyOf: - type: string - type: 'null' title: Quote description: 'The verbatim passage. This is the citation''s anchor: locate it in the document''s text rather than relying on any offset.' examples: - in no event shall either party be liable for indirect damages pageStart: anyOf: - type: integer - type: 'null' title: Pagestart description: First page the quote appears on. examples: - 1 pageEnd: anyOf: - type: integer - type: 'null' title: Pageend description: Last page the quote appears on. examples: - 1 citationRole: type: string title: Citationrole description: '`primary` for the strongest passage behind the fact, `support` for the others that were clustered with it.' default: support examples: - primary sourceAvailable: type: boolean title: Sourceavailable description: False when the document this quote came from is no longer in the workspace. The quote is still accurate (it is a snapshot), but there is nothing to fetch and nothing to highlight it in. examples: - false additionalProperties: false type: object required: - sourceAvailable title: FactCitation description: 'One verified passage behind a fact. An immutable snapshot taken when the set was generated, so it survives the document being deleted and the evidence being re-extracted. Resolve it by searching for `quote` inside `GET /v1/matters/{matterId}/documents/{id}/text`; that is the durable mechanism, and it is what the product''s own verifier uses.' FactSetCoverage: properties: included: type: integer title: Included description: Documents whose evidence went into this set. examples: - 1 total: type: integer title: Total description: Documents in the matter at generation time. examples: - 128 excluded: type: integer title: Excluded description: Documents in the matter that this generation did not read, because it hit the per-run inline ceiling. Generate again to pick up more. examples: - 1 additionalProperties: false type: object required: - included - total - excluded title: FactSetCoverage description: 'What the generation actually read, and what it did not. Not decoration. The reducer extracts at most 60 documents inline, so on a larger matter `included` is 60 and `excluded` is the rest, while the operation reports 60 of 60 and looks complete. It IS complete, for what it read. This is the only place that says what that was.' Pagination: properties: limit: type: integer title: Limit description: The `limit` that was applied to this request. examples: - 50 offset: type: integer title: Offset description: The `offset` that was applied to this request. examples: - 0 total: type: integer title: Total description: Total rows matching the filter, not the number returned in `data`. Use it to size a job before running it. examples: - 128 hasMore: type: boolean title: Hasmore description: True when rows remain beyond this window. Derived from `offset + len(data) < total`, so a full final page correctly reports `false` rather than sending you after an empty page. examples: - false additionalProperties: false type: object required: - limit - offset - total - hasMore title: Pagination description: 'Where the caller is, and whether there is more. `total` is the count of rows matching the filter, not the count returned, so a caller can size a job before running it.' Operation: properties: id: type: string title: Id description: Public identifier, `op_` followed by 32 hex characters. Poll `GET /v1/operations/{operationId}` with it. examples: - op_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 type: type: string title: Type description: What kind of work this is, for example `matrix.run` or `draft.generate`. examples: - matrix.run status: $ref: '#/components/schemas/OperationStatus' description: 'One of five values: `queued`, `running`, `succeeded`, `failed`, `cancelled`. There is no sixth and there are no synonyms. Stop polling once it is `succeeded`, `failed` or `cancelled`.' examples: - succeeded createdAt: type: string format: date-time title: Createdat description: When the operation was accepted (RFC 3339). examples: - '2026-08-19T14:32:10Z' completedAt: anyOf: - type: string format: date-time - type: 'null' title: Completedat description: When the operation reached a terminal status (RFC 3339). Present if and only if the status is terminal. examples: - '2026-08-19T14:32:10Z' matterId: anyOf: - type: string - type: 'null' title: Matterid description: '`mat_` identifier of the matter this work belongs to, when it belongs to one.' examples: - mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 resource: anyOf: - $ref: '#/components/schemas/OperationResource' - type: 'null' description: What the operation produced. Absent until the underlying job row exists, which an idempotent replay can briefly observe, so treat absence as 'not yet' rather than 'never'. error: anyOf: - $ref: '#/components/schemas/OperationError' - type: 'null' description: Why the work failed. Present only when `status` is `failed`. Partial success is `succeeded` with `progress.done < progress.total`, never an error. progress: anyOf: - $ref: '#/components/schemas/OperationProgress' - type: 'null' description: How far along the work is, when the underlying job reports it. Absent does not mean no progress. requestId: anyOf: - type: string - type: 'null' title: Requestid description: The `X-Request-ID` of the request that created this operation. Quote it in a support ticket. examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 additionalProperties: false type: object required: - id - type - status - createdAt title: Operation description: 'One long-running operation, whatever kind of work it is. Readable for `OPERATION_RETENTION_DAYS` after creation, per AIP-151.' ValidationProblem: type: object title: ValidationProblem description: A problem document for a schema rejection. `errors` lists the fields that were refused. The value you submitted is deliberately not echoed, so a validation failure cannot copy your content into an error response or into either side's logs. required: - type - title - status - detail - instance - errors properties: type: type: string format: uri description: The stable identifier for this error, and the one field to branch on. Resolves to a page describing it. examples: - https://vaquill.ai/docs/workspace-api/errors/insufficient-scope title: type: string description: A short human-readable summary. examples: - Insufficient scope status: type: integer description: The HTTP status code, repeated. examples: - 403 detail: type: string description: What went wrong on this specific request. May be reworded at any time. examples: - This credential carries matters:read. This operation needs matters:write. instance: type: string description: The path this problem occurred on. examples: - /workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 requestId: type: string description: The id of this request, identical to the `X-Request-ID` response header. Quote it when contacting support. examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 errors: type: array description: One entry per rejected field. items: type: object required: - location - message - type properties: location: type: string description: Dotted path to the rejected field, for example `body.contentMarkdown`. message: type: string description: Why it was rejected. type: type: string description: The validation rule that failed. additionalProperties: true OperationProgress: properties: done: type: integer minimum: 0.0 title: Done description: How many units are finished. examples: - 24 total: type: integer minimum: 0.0 title: Total description: How many units there are in total. Can legitimately be zero for an empty run. examples: - 128 unit: type: string enum: - cells - steps - documents - files - rows - percent title: Unit description: 'What `done` and `total` are counting. Always read it: a workflow run counts `percent` while a matrix run counts `cells`, so `{done: 43, total: 100}` alone is ambiguous.' examples: - cells additionalProperties: false type: object required: - done - total - unit title: OperationProgress description: 'How far along, and in what units. The unit is not decoration. A workflow run stores only a percentage while a matrix run stores cell counts, so `{done: 43, total: 100}` with no unit reads as 43 of 100 documents and a client builds a wrong estimate from it.' FactSetGenerateRequest: properties: mode: type: string enum: - standard - incremental title: Mode description: '`standard` re-reads every document in the matter. `incremental` reads only documents that changed since the current set, which is cheaper and reports its progress against the changed count rather than the matter size.' default: standard examples: - standard additionalProperties: false type: object title: FactSetGenerateRequest description: 'What to generate. Empty is valid and means `standard`. There is no `force` flag: on the Facts side that word is the delete-and-reinsert path through the shared evidence spine, and a caller that genuinely needs a rebuild changes something the corpus hash can see.' OperationResource: properties: kind: type: string title: Kind description: What sort of thing was produced, for example `matrix` or `document`. examples: - matrix id: type: string title: Id description: Public identifier of the produced resource, carrying its own type prefix, for example `mtx_` for a matrix. examples: - mtx_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 url: anyOf: - type: string - type: 'null' title: Url description: Path on this API where the resource can be read, RELATIVE to the API root and never absolute. Absent when the resource has no addressable path, which happens for work started outside a matter. Absent means the id is real and there is nowhere to GET it; it is not an error. examples: - https://storage.vaquill.ai/exports/msa-acme-v3-redline.docx?signature=... additionalProperties: false type: object required: - kind - id title: OperationResource description: 'What the operation produced, or is producing. `url` is a path on this API rather than an absolute URL, because the service is mounted today and gets its own hostname later (docs 07.5). A relative path survives that move; a baked-in host does not.' FactSet: properties: id: type: string title: Id description: '`fct_` identifier. The same id the operation''s resource carries.' examples: - fct_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 matterId: type: string title: Matterid description: The `mat_` matter this set covers. examples: - mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 status: $ref: '#/components/schemas/OperationStatus' description: The generation's status, in the same five values every operation uses. examples: - succeeded mode: type: string title: Mode description: How this set was generated. `standard` re-reads the matter, `incremental` reads only what changed. Sets generated from the web app may report `deep`, which this API does not accept. examples: - standard isCurrent: type: boolean title: Iscurrent description: True for the one set in force for this matter. Generating a new set makes the previous one `false`; nothing is deleted, and its facts stay readable. examples: - false isStale: type: boolean title: Isstale description: True when the matter's documents have changed since this set was built. Computed per request against the current document set, never stored. examples: - false changedDocCount: type: integer title: Changeddoccount description: How many documents the matter has gained since this set was generated. Zero with `isStale` true means documents were re-ingested rather than added. examples: - 1 coverage: $ref: '#/components/schemas/FactSetCoverage' description: What the generation read. factCount: anyOf: - type: integer - type: 'null' title: Factcount description: Facts in the set, once it has finished. examples: - 1 conflictCount: anyOf: - type: integer - type: 'null' title: Conflictcount description: Facts the reducer flagged as conflicted. examples: - 1 createdAt: type: string format: date-time title: Createdat description: When the generation was requested. examples: - '2026-08-19T14:32:10Z' completedAt: anyOf: - type: string format: date-time - type: 'null' title: Completedat description: When the generation finished. Null until it does. examples: - '2026-08-19T14:32:10Z' additionalProperties: false type: object required: - id - matterId - status - mode - isCurrent - isStale - changedDocCount - coverage - createdAt title: FactSet description: One generated ledger. Page_FactSet_: properties: data: items: $ref: '#/components/schemas/FactSet' type: array title: Data description: The rows in this window, in the collection's default order. pagination: $ref: '#/components/schemas/Pagination' description: Where this window sits in the full result set. additionalProperties: false type: object required: - data - pagination title: Page[FactSet] OperationError: properties: code: type: string title: Code description: Stable, machine-readable failure code. Branch on this, never on `message`. examples: - EXTRACTION_FAILED message: type: string title: Message description: Human-readable explanation, sanitized of internal paths and stack frames. Wording may change; do not parse it. examples: - The upstream extraction did not finish. additionalProperties: false type: object required: - code - message title: OperationError description: 'Why a failed operation failed, in terms a customer can act on. `code` is stable and machine-readable. `message` is sanitized: the internal job tables store stack traces and file paths in their `error_message` columns, and forwarding those verbatim leaks our internals into a customer''s logs.' FactSetExport: properties: format: type: string title: Format description: The format that was rendered. examples: - docx filename: type: string title: Filename description: A filename derived from the matter's own name. examples: - msa-acme-v3.docx sizeBytes: type: integer title: Sizebytes description: Decoded size, so you can check `content` round-tripped. examples: - 248193 content: type: string title: Content description: The file, base64-encoded. examples: - UEsDBBQABgAIAAAAIQ... factCount: type: integer title: Factcount description: How many facts the file contains. examples: - 1 additionalProperties: false type: object required: - format - filename - sizeBytes - content - factCount title: FactSetExport description: 'A rendered ledger, returned as bytes rather than as a signed URL. The renderers run on demand and write no object, so vending a URL would mean writing client work product to storage first. Encryption is on in every deployment, which leaves a choice between an object the customer cannot decrypt and plaintext in the bucket. Same reasoning as the draft export.' Problem: type: object title: Problem description: An RFC 9457 problem document. Branch on `type`, which is stable; `title` and `detail` are written for people and may be reworded. Some problems carry extra members (`requiredScopes`, `limit`, `expectedVersion`), which is why this object is open. required: - type - title - status - detail - instance properties: type: type: string format: uri description: The stable identifier for this error, and the one field to branch on. Resolves to a page describing it. examples: - https://vaquill.ai/docs/workspace-api/errors/insufficient-scope title: type: string description: A short human-readable summary. examples: - Insufficient scope status: type: integer description: The HTTP status code, repeated. examples: - 403 detail: type: string description: What went wrong on this specific request. May be reworded at any time. examples: - This credential carries matters:read. This operation needs matters:write. instance: type: string description: The path this problem occurred on. examples: - /workspace/v1/matters/mat_9f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 requestId: type: string description: The id of this request, identical to the `X-Request-ID` response header. Quote it when contacting support. examples: - req_5f2c8b1e4a7d43c9b6e0f1a2c3d4e5f6 additionalProperties: true securitySchemes: WorkspaceAuth: type: http scheme: bearer bearerFormat: vq_ws_* description: 'Workspace credential issued from the automation console at `/automation`. Send it as `Authorization: Bearer vq_ws_...`. This is NOT a Data API key: a `vq_key_` credential is refused here and names the other product in the error.' externalDocs: description: Getting started guide and error reference url: https://vaquill.ai/docs/workspace-api x-refined-from: - vaquill-ai-workspace-openapi.json - vaquill-ai-workspace-openapi.yml