UnderheardResearch
Underheard Research docs
For agentsOpen the app

Getting started

  • Research documentation
  • Your first study
  • Study design

Running research

  • Audiences and quotas
  • Recruitment and links
  • The respondent experience
  • Fieldwork and quality

Understanding results

  • Analysis and evidence
  • Quantitative methods
  • Reports and exports
  • Library and past research

For companies

  • Working with a research partner
  • Privacy and consent
  • Troubleshooting

Integrations

  • Integration planning
  • API access
  • API keys
  • REST API
  • Assistants and MCP
  • For agents
Manual pagesREST API

Getting started

  • Research documentation
  • Your first study
  • Study design

Running research

  • Audiences and quotas
  • Recruitment and links
  • The respondent experience
  • Fieldwork and quality

Understanding results

  • Analysis and evidence
  • Quantitative methods
  • Reports and exports
  • Library and past research

For companies

  • Working with a research partner
  • Privacy and consent
  • Troubleshooting

Integrations

  • Integration planning
  • API access
  • API keys
  • REST API
  • Assistants and MCP
  • For agents

REST API

The REST API covers the participant side of a study from your own systems: launch a study for your own people, add people to it, prepare and download their personal links, name one person, read the list, and read a study's shareable links. Everything else (creating and designing studies, reading results and analysis) is on the MCP server, which takes the same key.

Basics

  • Base URL: https://research.underheard.ai
  • Authentication: Authorization: Bearer <key>, an API key. Writes need a key that can edit.
  • Bodies: JSON, Content-Type: application/json. Responses are JSON unless noted.
  • Study id: the second segment of a study's address, /studies/<study id>/recruit, or research_list_studies over MCP.
  • Limits: a request body is at most 12 MB for people, 2 KB for links. A list holds at most 10,000 people.

Every response carries Cache-Control: private, no-store.

Launch a study for your own people

POST /api/research/studies/<study id>/launch
{ "targetCompletes": 50, "mode": "voice" }

Launches a study whose participants are your own people, as the Launch button on Recruit does: the newest published guide is pinned and fieldwork opens. Nothing is bought and nobody is contacted. targetCompletes is how many responses to collect (1 to 10,000). mode is optional (text, voice or mixed): voice for a voice-led guide and text otherwise.

The study's brief must say the participants are your own people (recruitmentIntent bring-own) and carry the decision, the audience and the experience mode, and the guide must be published. A study recruiting from the Underheard panel is refused with 422: it launches on Recruit, where the order and its cost are shown.

Response:

{
  "studyId": "811a7a3b-6a3a-4171-bc0f-2ef868a77ba5",
  "launched": true,
  "recruitmentPlanId": "...",
  "fieldwork": { "status": "active", "mode": "voice", "targetCompletes": 50, "launchedAt": "2026-10-23T09:00:00.000Z", "instrumentRevisionId": "..." },
  "links": {
    "study": { "path": "/take/<token>", "url": "https://research.underheard.ai/take/<token>", "enabled": true, "availability": "open" },
    "test": { "path": "/take/<token>", "url": "https://research.underheard.ai/take/<token>", "availability": "open", "interviews": [] }
  }
}

Calling it again after launch changes nothing and answers launched: false with the same links.

Add people to a study

POST /api/research/own-people
{
  "action": "add-people",
  "studyId": "811a7a3b-6a3a-4171-bc0f-2ef868a77ba5",
  "mode": "add",
  "source": "HubSpot list: Gold customers",
  "defaultCallingCode": "41",
  "people": [
    { "name": "Rami Haddad", "phone": "+971 50 123 4567", "email": "rami@example.com", "segments": { "Company": "Aurora Beauty", "Country": "UAE" } },
    { "name": "Lina Khoury", "email": "lina@example.com", "segments": { "Company": "Cedar Labs" } }
  ]
}
FieldRequiredMeaning
actionyesadd-people
studyIdyesThe study the list belongs to.
peopleyes1 to 10,000 people.
modenoadd (default) keeps the current list and skips people already on it; replace starts the list again.
sourcenoA label for where the list came from, shown above the list. Defaults to "the API".
defaultCallingCodenoDigits only, no plus, for example 971. Used for numbers written with a single leading zero. Defaults to the first of the study's markets that has one.

Per person:

FieldRequiredMeaning
namenoUsed in the greeting and in an invitation.
phonenoAny readable form. +, 00 and a leading 0 with a defaultCallingCode all resolve; anything else without a country code is left out rather than guessed.
emailnoNormalised to lower case.
segmentsnoUp to 40 of your own labels, each with a string or a number. They become the segments you compare in Fieldwork and Results.

A person needs a phone number or an email. One with neither is left out.

Response:

{ "added": 2, "skipped": 0, "people": 10, "leftOut": { "noContact": 0, "unreadablePhone": 0, "duplicatesInRequest": 0 }, "segments": ["company", "country"] }

added is how many were written; skipped how many were already on the list by phone or email; people the size of the list afterwards; leftOut the rows nobody could be reached on.

Prepare personal links

POST /api/research/own-people
{ "action": "prepare-links", "studyId": "<study id>", "personIds": ["p_1a2b3c4d5e6f"] }

Prepares a personal link for every person on the list who has none, or for the personIds given. The study has to be launched and fieldwork active. Links stay valid for 7 days; calling again reissues expired ones and leaves live ones alone.

Response:

{ "prepared": 120, "alreadyLinked": 30, "rejected": { "quota": 0, "target": 0 }, "liveLinks": 150 }

The links themselves are not in this response: fetch them with links-csv.

Download the links

POST /api/research/own-people
{ "action": "links-csv", "studyId": "<study id>" }

Returns text/csv with the columns Name, Phone, Email, one column per segment, Personal link, Link expires. One row per person with a live link. Send each person their own link through your own channel.

A link for one named person

POST /api/research/own-people
{ "action": "person-link", "studyId": "<study id>", "name": "Nina Roth" }

Adds a person with that name (no contact details) to the list and returns their personal link once:

{ "personId": "p_9f8e7d6c5b4a", "name": "Nina Roth", "link": "https://research.underheard.ai/respond/<token>", "expiresAt": "2026-10-26T09:00:00.000Z" }

Read the list

POST /api/research/own-people
{ "action": "list-csv", "studyId": "<study id>" }

Returns text/csv with Name, Phone, Email, one column per segment, and Opted out.

GET /api/research/own-people?studyId=<study id>

Returns the list as JSON: roster (the people, their segments, their links), tracking (how far each person got: not-invited, link-issued, invited, opened, started, completed), funnel (the counts), launched and liveLinks.

A study's shareable links

GET /api/research/study-links?studyId=<study id>
{
  "study": { "path": "/take/<token>", "url": "https://research.underheard.ai/take/<token>", "enabled": true, "availability": "open" },
  "test": { "path": "/take/<token>", "url": "https://research.underheard.ai/take/<token>", "availability": "open", "interviews": [] }
}

availability is one of open, not-launched, paused, closed, or not-own-people (a study launched before own people had a place in every plan; its path is null). enabled is whether the study link is turned on.

POST /api/research/study-links
{ "action": "set-enabled", "studyId": "<study id>", "enabled": false }
{ "action": "replace", "studyId": "<study id>", "kind": "study" }

set-enabled turns the study link off or on; the same address keeps working when turned on again. replace makes a new study link or test link (kind is study or test); the old address stops working.

Browser-only actions

With a key, the own-people route refuses import (the mapping drawer's upload), delete, opt-out and send with 403. Deleting a list, opting someone out and sending messages stay on screen, where the researcher sees the count and the message before pressing. So does launching a panel study.

Errors

StatusWhen
400The body is not JSON, a field is missing or malformed, or no person in the request has a usable phone or email.
401No key and no session, or a key that is revoked, expired or unknown.
403A read key on a write, a browser-only action with a key, a key whose owner left the workspace, or a browser request from another origin.
404The study does not exist or is not in the key's workspace.
409The study is not launched or fieldwork is not active, the list would pass 10,000 people, the study is full, the record changed under a concurrent write, or (on launch) the brief is incomplete, the guide is not published, or a prepared plan has another target.
413The body is too large. Split it.
422On launch: the study recruits from a panel. Launch it on Recruit.

Every error body is { "error": "..." } in plain words.

Example

curl -X POST https://research.underheard.ai/api/research/own-people \
  -H "Authorization: Bearer uh_research_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "add-people",
    "studyId": "811a7a3b-6a3a-4171-bc0f-2ef868a77ba5",
    "people": [
      { "name": "Rami Haddad", "phone": "+971501234567", "segments": { "Company": "Aurora Beauty" } },
      { "name": "Lina Khoury", "email": "lina@example.com", "segments": { "Company": "Cedar Labs" } }
    ]
  }'

Then launch, prepare the links and download them:

curl -X POST https://research.underheard.ai/api/research/studies/811a7a3b-6a3a-4171-bc0f-2ef868a77ba5/launch \
  -H "Authorization: Bearer uh_research_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "targetCompletes": 50 }'

curl -X POST https://research.underheard.ai/api/research/own-people \
  -H "Authorization: Bearer uh_research_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "action": "prepare-links", "studyId": "811a7a3b-6a3a-4171-bc0f-2ef868a77ba5" }'

curl -X POST https://research.underheard.ai/api/research/own-people \
  -H "Authorization: Bearer uh_research_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "action": "links-csv", "studyId": "811a7a3b-6a3a-4171-bc0f-2ef868a77ba5" }' -o personal-links.csv
PreviousAPI keysNextAssistants and MCP

On this page

  • Basics
  • Launch a study for your own people
  • Add people to a study
  • Prepare personal links
  • Download the links
  • A link for one named person
  • Read the list
  • A study's shareable links
  • Browser-only actions
  • Errors
  • Example

Questions: hello@underheard.ai. The same manual, as plain text for AI tools: /llms.txt and /llms-full.txt.