> ## 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.

# Agents

> Run your Harvey agents programmatically and collect their results

Harvey's Agents APIs let your systems run the agents your firm has built in Harvey, with the same instructions and knowledge sources they use in the web app. Discover an agent, start it on a prompt with any documents it should read, then poll for the answer, its citations, and any files it produced.

> [!NOTE]
>
> Rate limits are applied per workspace, per minute: **30** for listing agents, **60** for reading one, **10** for creating a thread, and **60** for reading a thread.

```bash theme={null}
GET  /api/v1/agents
GET  /api/v1/agents/{agent_id}
POST /api/v1/agent_threads
GET  /api/v1/agent_threads/{thread_id}
```

## Overview

Agent work is asynchronous. You create a **thread**, which holds the agent's run, and poll that thread until it reaches a terminal status. Creating a thread returns immediately with a thread id.

### Key Capabilities

* **Reuse Your Own Agents**: Run the agents your firm already built and published, without rebuilding their logic in your own systems
* **Attach Documents Per Run**: Send documents alongside the prompt for the agent to read
* **Grounded Answers**: Receive citations that name the source document, page, and quoted passage behind each claim
* **Collect Generated Files**: Retrieve memos, summaries, and other files the agent produced

### Before You Start

The Agents API must be enabled for your workspace. Until it is, every endpoint returns `404` rather than an authorization error. Contact your Account Manager or reach out to us at [support@harvey.ai](mailto:support@harvey.ai) to request it.

Your token needs the `Agents and workflows API` and `Use agents and workflows` permissions, set in the API Tokens section of your workspace settings.

API tokens act as your workspace's service user rather than as the person who created the token. For each agent you want to call:

1. **Share the agent with the workspace**, at `RUN` access or higher. An agent private to one person is invisible to the API, even if that person can run it in the web app.
2. **Share every Vault project and knowledge source the agent uses.** If the service user cannot reach an agent's sources, the agent itself becomes unreachable.
3. **Publish the agent.** Unpublished agents, and published agents with no instructions, cannot be listed or run.

An agent that fails any of these returns `404`, the same response as an agent that does not exist.

### The Request Cycle

Create a thread, then poll it until `status` is terminal:

```bash theme={null}
curl -X POST "https://api.harvey.ai/api/v1/agent_threads" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -F "agent_id=01a0d9c9-3334-7036-ad4a-d14db13b93ba" \
  -F "prompt=Summarize the termination rights in this agreement." \
  -F "files=@northwind-msa.pdf"
```

```json theme={null}
{
  "id": 1671319,
  "status": "IN_PROGRESS",
  "harvey_url": "https://app.harvey.ai/assistant/assist/1671319"
}
```

```bash theme={null}
curl "https://api.harvey.ai/api/v1/agent_threads/1671319" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE"
```

Store the `id` it returns — it is the only handle you get on the thread, and how you read the result.

## Use Cases

### Use Case 1: Discover the Agents You Can Run

**Challenge**: An integration hardcoding agent names breaks the moment someone renames or replaces an agent, and there is no reliable way to tell which agents the integration is actually allowed to run.

**Solution**: List the agents available to your workspace and store the `agent_id` values you need. Pass back `pagination.next_cursor` until `has_more` is `false`.

```bash theme={null}
GET /api/v1/agents?limit=20
```

Harvey prebuilt agents and agents shared in from another workspace are not listed, but they can still be run if you know their `agent_id`.

### Use Case 2: Confirm an Agent Before Running It

**Challenge**: A stored `agent_id` can go stale — the agent may be unpublished, its knowledge sources may have moved out of reach, or it may have been republished with different behavior.

**Solution**: Read the agent before a scheduled batch. It resolves exactly as creating a thread would, so an id it returns is an id the run endpoint accepts.

```bash theme={null}
GET /api/v1/agents/{agent_id}
```

Compare `version_id` against the value you last stored to detect that an agent was republished. A run always executes the latest published version and cannot be pinned to an earlier one.

### Use Case 3: Run an Agent Over Incoming Documents

**Challenge**: Contracts arrive continuously from counterparties, vendors, and internal teams, and each needs the same first-pass review before a lawyer sees it.

**Solution**: Create a thread from your intake pipeline, attaching the document for the agent to read.

```bash theme={null}
curl -X POST "https://api.harvey.ai/api/v1/agent_threads" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -F "agent_id=01a0d9c9-3334-7036-ad4a-d14db13b93ba" \
  -F "prompt=Review this agreement against our standard positions and flag deviations." \
  -F "client_matter_id=2024-0147" \
  -F "files=@northwind-msa.pdf" \
  -F "files=@side-letter.docx"
```

Send up to 50 files, 100 MB per file and 100 MB across the whole request. If any file's type or size is not accepted, the entire request is refused and no thread is created, so a thread never silently loses a document.

### Use Case 4: Attribute Agent Work to a Client Matter

**Challenge**: Work run through an integration still needs to reach the right client and matter for billing, retention, and conflicts.

**Solution**: Pass `client_matter_id` when creating a thread. It accepts either the matter UUID that [`GET /api/v1/client_matters`](/guides/client_matters) returns as `id`, or the matter's name.

The response reports the matter it resolved to, as a UUID, even when you supplied a name. If your workspace requires a client matter on every query, omitting it returns `400` with the code `RUN_REFUSED`.

### Use Case 5: Return Results to Your Own System

**Challenge**: Reviewers work in a matter management or contract system, not in Harvey, and need the agent's conclusions where they already are.

**Solution**: Once `status` is `COMPLETED`, read `output.text` for the answer and `output.citations` for the sources behind it. Each citation names the source document, the page it appears on, and the quoted passage, with `<mark>` wrapping the quoted span.

```json theme={null}
{
  "citation_number": 1,
  "file_id": "66fead63-460e-4426-a179-39c70b224a99",
  "file_name": "northwind-msa.pdf",
  "citation_page": 12,
  "citation_quote": "Either party may terminate this Agreement upon <mark>thirty days' written notice</mark>."
}
```

Files the agent generated are listed under `output.files`. Fetch their bytes with `POST /api/v1/files/download` using `file_id`. To hand the work to a person instead, link them to `harvey_url`.

## Best Practices

### Poll on Terminal Status

Read `status` and stop when it is `COMPLETED`, `ERRORED`, or `CANCELLED`. Do not wait for a specific non-terminal value, and do not treat a `200` as meaning the thread has finished — an in-progress thread returns `200` as well.

### Write Specific Prompts

* **Avoid**: "Review this contract"
* **Use**: "Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period."

Prompts can be up to 4,000 characters.

### Switch on Error Codes

Requests rejected before a thread is created carry a machine-parseable `code`. Switch on it rather than matching message text, which is localized and may change.

## Error Handling

The Agents APIs use standard HTTP status codes. Anything your workspace cannot reach returns `404` rather than `403` — one `404` covers a resource that does not exist, one belonging to another workspace, and one you lack access to. An ethical wall is the only case that returns `403`.

| Status Code | Description | Example Error Message |
| - | - | - |
| 200 | Success | N/A |
| 202 | Accepted – Thread created | N/A |
| 400 | Bad Request – Invalid body, id, or client matter | `{ "error": { "code": "INVALID_AGENT_ID", "message": "Invalid agent id." } }` |
| 401 | Unauthorized – Invalid API key or permission | `{ "error": "Unauthorized" }` |
| 403 | Forbidden – Blocked by an ethical wall policy | `{ "error": "This action is blocked by an ethical wall policy" }` |
| 404 | Not Found – Agent or thread not reachable | `{ "error": "Agent not found" }` |
| 415 | Unsupported Media Type – Body was not multipart | `{ "error": { "code": "UNSUPPORTED_MEDIA_TYPE", "message": "Agent threads accept a multipart/form-data body." } }` |
| 429 | Too Many Requests – Rate limit exceeded | `{ "error": "Rate limit exceeded" }` |
| 500 | Internal Server Error | `{ "error": "An internal error occurred" }` |

Requests to `POST /api/v1/agent_threads` that are rejected before the thread is created return one of these codes:

| Code | Cause |
| - | - |
| `INVALID_REQUEST_BODY` | A missing, misspelled, or unrecognized form field, or a file sent under a field name other than `files` |
| `INVALID_AGENT_ID` | `agent_id` is not a valid UUID |
| `RUN_REFUSED` | A required `client_matter_id` was omitted, names no matter in your workspace, or names one you may not use |
| `FILE_REJECTED` | A document's type or size is not accepted |
| `UNSUPPORTED_MEDIA_TYPE` | The body was not `multipart/form-data` |

***

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


## Related topics

- [Get Agent](/api-reference/agents/get-agent.md)
- [List Agents](/api-reference/agents/list-agents.md)
- [Create Agent Thread](/api-reference/agents/create-agent-thread.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.