curl --request POST \
--url https://api.harvey.ai/api/v1/agent_threads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form agent_id=01a0d9c9-3334-7036-ad4a-d14db13b93ba \
--form 'prompt=Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.' \
--form client_matter_id=2024-0147 \
--form files=@example-fileimport requests
url = "https://api.harvey.ai/api/v1/agent_threads"
files = { "files": ("example-file", open("example-file", "rb")) }
payload = {
"agent_id": "01a0d9c9-3334-7036-ad4a-d14db13b93ba",
"prompt": "Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.",
"client_matter_id": "2024-0147"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('agent_id', '01a0d9c9-3334-7036-ad4a-d14db13b93ba');
form.append('prompt', 'Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.');
form.append('client_matter_id', '2024-0147');
form.append('files', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.harvey.ai/api/v1/agent_threads', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.harvey.ai/api/v1/agent_threads",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.harvey.ai/api/v1/agent_threads"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.harvey.ai/api/v1/agent_threads")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.harvey.ai/api/v1/agent_threads")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"id": 1671319,
"status": "IN_PROGRESS",
"agent_id": null,
"client_matter_id": "4f21c0b8-9d3e-4a77-8c21-6b0e5d9a1f34",
"harvey_url": "https://app.harvey.ai/assistant/assist/1671319",
"created_at": "2026-10-09T05:12:59.454218Z",
"output": null,
"error": null,
"files": [
{
"name": "northwind-msa.pdf",
"processing_status": "UPLOADED",
"failure_category": null,
"error": null
}
]
}Create Agent Thread
Creates a thread that runs the agent on a prompt, optionally with documents to read, and returns immediately with a thread id. The agent runs asynchronously. Get agent thread for the answer.
curl --request POST \
--url https://api.harvey.ai/api/v1/agent_threads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: multipart/form-data' \
--form agent_id=01a0d9c9-3334-7036-ad4a-d14db13b93ba \
--form 'prompt=Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.' \
--form client_matter_id=2024-0147 \
--form files=@example-fileimport requests
url = "https://api.harvey.ai/api/v1/agent_threads"
files = { "files": ("example-file", open("example-file", "rb")) }
payload = {
"agent_id": "01a0d9c9-3334-7036-ad4a-d14db13b93ba",
"prompt": "Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.",
"client_matter_id": "2024-0147"
}
headers = {"Authorization": "Bearer <token>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('agent_id', '01a0d9c9-3334-7036-ad4a-d14db13b93ba');
form.append('prompt', 'Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.');
form.append('client_matter_id', '2024-0147');
form.append('files', '<string>');
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};
options.body = form;
fetch('https://api.harvey.ai/api/v1/agent_threads', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.harvey.ai/api/v1/agent_threads",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: multipart/form-data"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.harvey.ai/api/v1/agent_threads"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.harvey.ai/api/v1/agent_threads")
.header("Authorization", "Bearer <token>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.harvey.ai/api/v1/agent_threads")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"agent_id\"\r\n\r\n01a0d9c9-3334-7036-ad4a-d14db13b93ba\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nSummarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period.\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"client_matter_id\"\r\n\r\n2024-0147\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"files\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"id": 1671319,
"status": "IN_PROGRESS",
"agent_id": null,
"client_matter_id": "4f21c0b8-9d3e-4a77-8c21-6b0e5d9a1f34",
"harvey_url": "https://app.harvey.ai/assistant/assist/1671319",
"created_at": "2026-10-09T05:12:59.454218Z",
"output": null,
"error": null,
"files": [
{
"name": "northwind-msa.pdf",
"processing_status": "UPLOADED",
"failure_category": null,
"error": null
}
]
}Permissions
RequiresAgents and workflows API and Use agents and workflows permissions. If these permissions are not available to select, contact support@harvey.ai.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
The agent to run in the new thread.
"01a0d9c9-3334-7036-ad4a-d14db13b93ba"
The instruction for the agent to execute.
1 - 4000"Summarize the termination rights in this agreement. For each, state who may exercise it, the notice period, and any cure period."
Client matter to attribute the work to. Accepts either the matter's id or name. Required if your workspace requires a client matter on every query.
1 - 128"2024-0147"
A document for the agent to read. Repeat the field once per document. Up to 50 files, 100 MB per file and 100 MB across the whole request. A file whose type or size is not accepted refuses the entire request.
Response
Thread created.
A thread and the agent run it holds.
The unique identifier of the agent thread.
Lifecycle state of a thread. COMPLETED, ERRORED and CANCELLED are terminal.
PENDING, IN_PROGRESS, COMPLETED, ERRORED, CANCELLED The agent this thread ran. Null until the agent begins executing.
The client matter this thread is attributed to, as a UUID, even if you supplied a name. Null when none was supplied.
Link to the thread in the Harvey web app, for handing the work to a person.
When the thread was created.
What the agent produced. Null until status is terminal, and on a thread that produced no answer.
Show child attributes
Show child attributes
Why the thread did not complete. Null unless status is ERRORED or CANCELLED.
The documents you attached, each with the processing status recorded for it. Generated files live under output.files instead.
Show child attributes
Show child attributes