> ## Documentation Index
> Fetch the complete documentation index at: https://developers.harvey.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Review Tables

> Read results from and add rows to Vault review tables

Harvey's Review Table APIs let your systems programmatically read a review table's structure and results, and add new documents as rows without rebuilding the table in the UI. Review tables are built on top of Vault, so the documents a table reviews are uploaded and managed through the [Vault APIs](/guides/vault) first.

<Note>
  The current API request rate limits for Review Table API endpoints are **10 requests per minute**.
</Note>

```bash theme={null}
GET /api/v1/vault/review_table/{review_table_id}
GET /api/v1/vault/get_row/{review_table_id}/{file_id}
POST /api/v1/vault/add_row/{review_table_id}
```

## Overview

A review table extracts structured answers from the documents in a Vault project — one row per document (or file group), one column per question. Use these APIs to:

* **Export Results**: Read a table's title, file list, and per-row cells, including Harvey's answers, reasoning, citations, and verification status
* **Extend a Table**: Add new documents as rows — individually or grouped — and have Harvey review them against the table's existing columns

## Use Cases

### Use Case 1: Fetch Review Table Data

**Challenge**: After a review table has been run in Vault, teams need to programmatically access the table's structure and results — for example, to export answers, check verification status, or build downstream workflows.

**Solution**: Use `review_table_ids` from Get Project Metadata to discover available review tables, then retrieve each table's metadata (title, file list) and drill into individual row results.

**Step 1** — Get the project's review table IDs from the metadata endpoint:

```bash theme={null}
curl -X GET "https://api.harvey.ai/api/v1/vault/get_metadata/{project_id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

The response includes a `review_table_ids` array (e.g., `[2365724, 2365725]`). An empty array means the project has no review tables.

**Step 2** — Fetch a review table's metadata by ID to get its title and file list:

```bash theme={null}
curl -X GET "https://api.harvey.ai/api/v1/vault/review_table/{review_table_id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

The response contains the table's `title`, `created_at` timestamp, and `file_ids` — one ID per document row in the table.

**Step 3** — Retrieve a specific row using the `review_table_id` and a `file_id` from the previous step:

```bash theme={null}
curl -X GET "https://api.harvey.ai/api/v1/vault/get_row/{review_table_id}/{file_id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Each row contains an array of `cells` with the column name, Harvey's short answer (`summary`), the full reasoning behind it (`additional_context`), supporting `citations`, and verification/flag status. Files reviewed together as a file group share a single row: requesting any file in the group returns that shared row, with `file_id` echoing the file you asked for. Within each field, a user-edited value takes precedence over the AI-generated value. Inline citation markers in `summary` and `additional_context` use `[N]` bracket notation, where `N` is the 1-based index into the cell's `citations` array.

### Use Case 2: Add New Rows to an Existing Review Table

**Challenge**: Review tables are often long-lived — new documents arrive after the table was first run, and teams want them reviewed against the same columns without rebuilding the table in the UI. Sometimes a single row needs to cover several related documents, such as a master agreement and its amendments.

**Solution**: Use the add row endpoint to add files from the review table's Vault project as new rows. Harvey schedules a review run that populates each new row's cells for every existing visible column.

**Step 1** — Upload the files to the review table's Vault project (or pick existing files) and wait until each `processing_status` reaches `ready_to_query`:

```bash theme={null}
curl -X GET "https://api.harvey.ai/api/v1/vault/get_files?ids={file_id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Step 2** — Add the files to the review table. Pass a single ID in `file_ids` to add one file as its own row:

```bash theme={null}
curl -X POST "https://api.harvey.ai/api/v1/vault/add_row/{review_table_id}" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_ids": ["0199c5c1-50d9-7d60-93aa-cd65c3b7d5a9"]}'
```

The response confirms the run was scheduled. `review_file_group_id` is `null` because a single file becomes its own row:

```json theme={null}
{
  "response": {
    "event_id": 2365724,
    "file_ids": ["0199c5c1-50d9-7d60-93aa-cd65c3b7d5a9"],
    "review_event_run_id": "019f8d8f-fc20-79e0-8b78-980b747c5ef3",
    "review_file_group_id": null,
    "status": "scheduled"
  }
}
```

**Step 3** — The run is asynchronous. Poll the row endpoint until its cells are populated:

```bash theme={null}
curl -X GET "https://api.harvey.ai/api/v1/vault/get_row/{review_table_id}/{file_id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

#### Reviewing several files together as one row

Pass two or more IDs in `file_ids` to create a **file group** — the files are reviewed together and occupy a single row in the table, so each cell answers across the whole set of documents. Use the optional `group_name` to label the group:

```bash theme={null}
curl -X POST "https://api.harvey.ai/api/v1/vault/add_row/{review_table_id}" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "file_ids": [
      "0199c5c1-50d9-7d60-93aa-cd65c3b7d5a9",
      "019f66b0-5706-7239-b7b8-9c61cbec8b7a"
    ],
    "group_name": "Acme MSA and amendments"
  }'
```

The response returns the ID of the group that was created:

```json theme={null}
{
  "response": {
    "event_id": 2365724,
    "file_ids": [
      "0199c5c1-50d9-7d60-93aa-cd65c3b7d5a9",
      "019f66b0-5706-7239-b7b8-9c61cbec8b7a"
    ],
    "review_event_run_id": "019f97bd-6d6c-7715-b63e-a0a11437f202",
    "review_file_group_id": "019f97bd-6d57-7aaf-9559-58812be0e1a7",
    "status": "scheduled"
  }
}
```

Because the group is a single row, poll it with `get_row` using any member file ID — each member resolves to the same grouped row.

A few rules to keep in mind:

* Every file must belong to the same Vault project the review table was created from; files from other projects return `404`.
* A file that already has a row returns `409`. For a group request, a file that already belongs to a file group in the table also returns `409`. A file that is still processing returns `409` too — retry once it reaches `ready_to_query`. In each case the error message names the offending file ID.
* `group_name` defaults to the first file's name, and is ignored when only one file is sent.
* A request may carry up to 25 files by default; workspaces with a raised file-group limit may send more. Repeating the same ID in one request returns `400`.
* Adding several files at once always creates one grouped row rather than several individual rows. To add multiple independent rows, send one request per file.
* File grouping must be enabled for your workspace; multi-file requests return `422` otherwise. Adding an already-grouped file as its own row also returns `422`.
* Re-adding a file whose row was previously deleted restores the original row instead of creating a duplicate.

## Error Handling

| Status Code | Description                                              | Example Error Message                         |
| ----------- | -------------------------------------------------------- | --------------------------------------------- |
| 200         | Success                                                  | N/A                                           |
| 400         | Bad Request – Missing or invalid input                   | `{ "error": "Duplicate file id" }`            |
| 401         | Unauthorized – Invalid API key                           | `{ "error": "Unauthorized" }`                 |
| 404         | Not Found – Review table or file not found               | `{ "error": "File not found" }`               |
| 409         | Conflict – File already has a row or is still processing | `{ "error": "File already has a row" }`       |
| 422         | Unprocessable – File grouping not enabled for workspace  | `{ "error": "File grouping is not enabled" }` |
| 500         | Internal Server Error                                    | `{ "error": "Unexpected server error" }`      |

***

Need help getting started? Contact your Harvey Customer Success Manager for more information.
