---
title: "Read a vault's document table"
method: GET
path: "/vaults/{id}/documents"
tags: ["Contract Intelligence"]
---

# Read a vault's document table

`GET /vaults/{id}/documents`

## Request

- Base URL: `https://app.gc.ai/api/external/v1`
- URL: `https://app.gc.ai/api/external/v1/vaults/{id}/documents`
- Auth: API key in header `Authorization`
- TypeScript: <https://skmtc.dev/gc-ai/apis/gc-ai-external-api/docs/vaults/:id/documents/get.ts> (a function with typed inputs; its response is checked against the schema)

Read the extracted table of a Contract Intelligence vault: one row per document, with every column the vault scans for.

A document appears here once its first scan writes values, which is a few minutes after upload. Until then poll `GET /files/{id}` with the `id` that `POST /vaults/{id}/documents` returned.

Filtering and sorting run in the database over the whole vault, so `total` counts every matching document and not just the page. Both name their target by the column `field_key` that `GET /vaults/{id}/columns` reports. A `sort` or `filter` naming a column the vault does not have returns `400`, and so does a filter whose value does not fit its operator, because a silently dropped rule paired with a confident `total` is worse than a rejected request.

Pass `filter` as a URL-encoded JSON array of rules, each `{"field","operator","value"}`, where `field` is a column `field_key`. For example `filter=[{"field":"governingLaw","operator":"equals","value":"Delaware"}]`. Operators that take no value (`is_empty`, `is_not_empty`) omit it; `number_range` and `date_range` take `{"from","to"}` with either side optional; `in` and `equals_only` take an array. Rules combine with AND.

A page holds at most 200 rows. `total` scans the whole filtered vault, so a client paging quickly can pass `include_total=false` and read the count on its own cadence.

Requires a user-scoped API key (`u:gcai_...`). A vault is shared with named people, so an organization-scoped key has no identity to resolve vault access with.

## Path parameters

- `id` string, uuid, required: The vault ID

## Query parameters

- `limit` integer: Max rows to return (default 100, max 200)
- `offset` integer, nullable: Number of items to skip (default 0)
- `search` string: Case-insensitive substring match on the document name, the upload filename, or the Document Name column.
- `filter` string: URL-encoded JSON array of filter rules. See the description for the shape and the operators.
- `sort` string: Column `field_key` to sort by. Also accepts `fileName` (the upload filename), `extractedAt`, and `sourceName`. Defaults to `fileName`, ascending.
- `sort_direction` 'asc' | 'desc': Sort direction. Defaults to `asc`.
- `include_total` 'true' | 'false': When `false`, skip the whole-vault count and return `total: null`. Defaults to `true`.
- `include_deleted` 'true' | 'false': When `true`, also return soft-deleted documents and the copies GC AI removed as duplicates. Reading deleted documents needs the same rights as deleting them, so this requires the `editor` or `owner` role plus the organization-level permission to manage vaults. Defaults to `false`.

## Response `200`

A page of the document table

- VaultDocumentListResponse
  - `documents` VaultDocumentRow[], required
    - `document_id` string, uuid, required: Stable identifier for this row. Use it with `GET`, `DELETE`, and `POST .../restore` on this path. One upload can hold several documents (GC AI splits a bundled PDF into the agreements inside it), and each of those is its own row with its own `document_id`. A document stored before GC AI split bundled uploads carries its `file_id` here.
    - `file_id` string, uuid, required: The upload this row came from: the `id` returned by `POST /vaults/{id}/documents` and the id `GET /files/{id}` takes. Rows that share a `file_id` came from one upload.
    - `name` string, required: The name shown in the vault: the document title when the vault has named this row, and the upload filename otherwise.
    - `file_name` string, required: Filename of the upload, unchanged.
    - `source_name` string, nullable, required: The vault source this document arrived through, such as the connected folder name. Null for a source with no name.
    - `source_provider` string, nullable, required: The source type, such as `manual_upload`, `google_drive`, or `sharepoint`.
    - `extracted_at` string, nullable, required: ISO 8601 timestamp of the most recent value written to this row, or null before the first value lands.
    - `is_extraction_active` boolean, required: True while a scan of this document is queued or running, so some cells may still be empty or change. Poll the row until it is false.
    - `deleted_at` string, nullable, required: ISO 8601 timestamp of the soft delete, or null for a live row. Only rows requested with `include_deleted=true` can carry a value.
    - `removed_as_duplicate_at` string, nullable, required: ISO 8601 timestamp when GC AI removed this row as a copy of another document in the vault, or null. `include_deleted=true` also returns these copies, so this field says why a row with a null `deleted_at` is in that list.
    - `values` object, required: One entry per column of the vault, keyed by the column `field_key`. Every row of a vault carries the same keys, so the response reads as a table. Read the keys, labels, and types from `GET /vaults/{id}/columns`.
  - `total` number, nullable, required: Rows matching the filters across the whole vault, not just this page. Null when the request passed `include_total=false`, which skips the count.
  - `pagination` Pagination, required
    - `limit` number, required: Page size
    - `offset` number, required: Current offset
    - `has_more` boolean, required: Whether more results exist

## Other responses

- `400`: Invalid query parameters, malformed `filter` JSON, or a `filter` or `sort` naming a `field_key` this vault does not have
- `401`: Missing or malformed API key
- `403`: Contract Intelligence is not enabled for this account. Contact support to request access., or `include_deleted` was used by a caller who cannot remove documents
- `404`: Vault not found, archived, or access denied
- `422`: Vault access is per-user and requires a user-scoped API key (u:gcai_...).
- `429`: Rate limit exceeded. See [Rate Limits](https://docs.gc.ai/api-reference/concepts/rate-limits) for the tiers, limits, and how to back off.
- `500`: Internal server error
- `503`: Service temporarily unavailable

---

[API](https://skmtc.dev/gc-ai/apis/gc-ai-external-api.md) - [All operations](https://skmtc.dev/gc-ai/apis/gc-ai-external-api/llms.txt) - [OpenAPI document](https://skmtc.dev/gc-ai/apis/gc-ai-external-api/revisions/2bbdfddf7107?raw)
