Step 3: Collect phone data with an extraction code

Add MCP server to your AI tool

Allow AI tools and LLMs to interact with the API documentation portal through MCP.

MCP server URL

https://docs.usehearsay.com/mcp

Standard setup for AI tools providing an mcp.json file

mcp.json
{
  "Partner APIs MCP server": {
    "url": "https://docs.usehearsay.com/mcp"
  }
}

Close

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 dueDate and the custodian details.
  • Custodian: custodianName, custodianEmail, custodianPhone.
  • requestedSources: what you want collected. For phones, use ios, android or 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. See ExtractionCodeConfigDto in the reference. If you send config, its type is required.
  • Delivery: set sendEmail: true and give a custodianEmail, 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 it extractionCode.

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 its code, custodian and dataSources.
  • For a phone, a data source has type ios or android. It also has a status, an itemsCount, a name (the device name), and a sourceId, 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"
}