Rules for every call

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

These rules apply to every request in this guide.

Base URL

The base URL is https://api.usehearsay.com. All paths in this guide are relative to it.

Headers on authenticated calls

Header Value
Authorization Bearer <token> (see "Step 1")
organization The id of the organization you are acting in

The sign-in routes need no token: register, login, refresh, the email-availability check and the two password-reset routes. Every other route needs the Authorization header.

Almost every case, extraction-code, conversation and export route requires the organization header. If it is missing or wrong, the call fails even with a valid token. Each endpoint in the reference lists the header when it needs it.

Response envelope

Every success response is wrapped:

  • data: the actual result.
  • statusCode: the HTTP status.
  • timestamp: the time of the response.

Always read the result from data. Treat any 2xx status as success: most creates return 201, and so do some updates.

Lists and paging

List routes accept page and perPage (or skip and limit), plus sortBy and sortOrder. The default is page 1 with 10 rows per page.

A list response has one more level: data holds a page object, and the rows are in data.data. The page object also carries total, totalPages, nextPage and previousPage.

To read everything, keep requesting pages until nextPage is null. Do not assume one page holds every row. If the order matters, send sortBy and sortOrder yourself instead of relying on the defaults.

Errors

An error response has statusCode, timestamp, path and message. message can be a string, or an object with a machine-readable code. When a code is present, branch on the code, not on the message text.

Rate limits

The API allows about 200 requests per minute. Some auth routes have lower limits; for example, the email-availability check allows 10 per minute. On HTTP 429, wait and retry with backoff. Do not retry in a tight loop.

Ids

Every id (case, extraction code, export, device, message, tag, file) is a 24-character hex string. Store the ids the API returns; never build or guess them.

The one exception is the extraction code's code, the short value the custodian types in (for example K7Q2-9XPL). Routes that take {extractionCode} expect that code value, not an id.

Where to find each id:

You need Where it is
Organization id data.userProfile.userOrganizations[].organization.id (login or register)
Case id data.case.id (create case); data.data[].case.id (list cases)
Extraction code data.code for the code value, data.id for its id (create code)
Device id data.data[].dataSources[].sourceId on iOS and Android rows (data-status-v2)
Conversation id data.data[].id (GET /conversation/search)
Message id data.data[].id (GET /conversation/search-entries and the message searches)
Tag id data.data[].id (GET /case/tags/{caseId})
Export id data.id (start export); data.data[].id (list exports)
File id file.id on a completed export

Dates

Send dates as ISO 8601, for example 2026-11-30T00:00:00.000Z.

An authenticated request:

curl "https://api.usehearsay.com/case?page=1&sortBy=updatedAt&sortOrder=desc" \
  -H "Authorization: Bearer $TOKEN" \
  -H "organization: $ORG_ID"

A single result:

{
  "data": { "...": "the result" },
  "statusCode": 200,
  "timestamp": "2026-01-15T10:15:00.000Z"
}

A list result. The rows are in data.data:

{
  "data": {
    "data": [{ "...": "one row" }],
    "page": 1,
    "perPage": 10,
    "total": 42,
    "totalPages": 5,
    "nextPage": 2,
    "previousPage": null
  },
  "statusCode": 200,
  "timestamp": "2026-01-15T10:15:00.000Z"
}