An extraction code is a one-time code you give to a custodian: the person whose phone holds the data. The custodian enters the code in the Hearsay desktop app, connects their phone, and the app uploads the selected data into your case. Your integration creates the code, delivers it, and then waits for the upload.
Create a code
POST /case/{caseId}/extraction
- No field is strictly required, but set
dueDateand the custodian details. - Custodian:
custodianName,custodianEmail,custodianPhone. requestedSources: what you want collected. For phones, useios,androidor both.label: a name you choose, to tell codes apart.config: collection settings, for example a date range, which apps may be shared, and attachments. SeeExtractionCodeConfigDtoin the reference. If you sendconfig, itstypeis required.- Delivery: set
sendEmail: trueand give acustodianEmail, and Hearsay emails the code to the custodian. If you leave either out, no email is sent; you must pass the code to the custodian some other way. sendReminders: optional automatic reminder emails, before the due date and after the code was issued.- Save the code value from
data.code. Later routes call itextractionCode.
Leave these fields alone unless Hearsay tells you otherwise: the payment fields (paymentRequired, paymentAmount, prepaidItems and so on), ocRequired, and the deprecated allowShareAll (use config instead).
Update a code
PATCH /case/{caseId}/extraction/{extractionCode}
- You can change the label, due date, configuration and custodian details.
- Once a code is locked (
lockCode), its configuration cannot change; the call returns an error. Set the configuration right at creation where you can. - To change only the custodian's contact details, use
PATCH /case/{caseId}/extraction/{extractionCode}/custodian. By default it sends the code email again when the email address changes. - To send or resend the email, use
POST /case/{caseId}/extraction/{extractionCode}/send-email.
List codes
GET /case/{caseId}/extraction returns the case's codes with their upload status. You can filter with searchText or extractionCode, and page through the results.
Know when the phone data has arrived
There is no callback. Poll GET /case/{caseId}/data-status-v2:
- The entries are in
data.data, one per extraction code, each with itscode,custodiananddataSources. - For a phone, a data source has
typeiosorandroid. It also has astatus, anitemsCount, aname(the device name), and asourceId, which is the device id you need for Steps 4 and 5. - Start the export only after the phone source shows a completed status and a non-zero
itemsCount. - Poll every few minutes, not every few seconds. A phone upload can take hours, and a custodian may take days to act.
Read device details
GET /device/{deviceId} (with the sourceId from data-status-v2) returns the phone's details and which kinds of data it holds. PATCH /device/{deviceId} changes its display name, manufacturer, brand or model.
Create a code and email it to the custodian:
curl -X POST "https://api.usehearsay.com/case/$CASE_ID/extraction" \
-H "Authorization: Bearer $TOKEN" \
-H "organization: $ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"dueDate": "2026-11-15T00:00:00.000Z",
"label": "Primary phone",
"custodianName": "Jane Doe",
"custodianEmail": "jane.doe@example.com",
"requestedSources": ["ios"],
"sendEmail": true,
"sendReminders": { "dueIn3Days": true }
}'
The code is data.code:
{
"data": {
"id": "507f1f77bcf86cd799439013",
"code": "K7Q2-9XPL",
"label": "Primary phone",
"name": "Jane Doe",
"email": "jane.doe@example.com",
"status": "pending"
},
"statusCode": 201,
"timestamp": "2026-01-15T10:15:00.000Z"
}
Poll for the upload:
curl "https://api.usehearsay.com/case/$CASE_ID/data-status-v2" \
-H "Authorization: Bearer $TOKEN" \
-H "organization: $ORG_ID"
The phone is ready when its source is completed and has items. sourceId is the device id:
{
"data": {
"data": [
{
"code": "K7Q2-9XPL",
"custodian": { "name": "Jane Doe", "email": "jane.doe@example.com" },
"dataSources": [
{
"type": "ios",
"name": "iPhone 15",
"status": "completed",
"itemsCount": 1250,
"sourceId": "507f1f77bcf86cd799439012"
}
]
}
]
},
"statusCode": 200,
"timestamp": "2026-01-15T10:15:00.000Z"
}