> ## Documentation Index
> Fetch the complete documentation index at: https://docs.userintuition.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Search research

> Search canonical study plans and report content across authorized studies without returning generated prose.

Use `POST /api/public/v1/research/search/` to find relevant evidence in studies whose reports have been indexed.

```sh theme={null}
curl --request POST \
  --url https://api.userintuition.ai/api/public/v1/research/search/ \
  --header "Authorization: Bearer $USERINTUITION_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "query": "What makes people think The Ribbon is too expensive?",
    "filters": {
      "study_ids": ["11111111-2222-3333-4444-555555555555"],
      "content_types": ["study_finding", "participant_response"],
      "research_date_from": "2026-01-01",
      "research_date_to": "2026-09-16"
    },
    "limit": 10,
    "cursor": null
  }'
```

## Content types

| Value | `content` schema |
| - | - |
| `study_plan` | The same section object returned by `get_study.study_plan` |
| `study_finding` | A report section, including `reference_ids` |
| `participant_profile` | A report section, including `reference_ids` |
| `participant_response` | One interview summary with `interview_id`, `overall_takeaways`, and `learning_goal_responses` |
| `recommended_next_step` | One structured report recommendation |

Search ranks candidate content IDs. The API validates those IDs against the current database index and hydrates `content` from persisted canonical JSON. It never returns generated answer text; `generated_content_returned` is always `false`.

Results are grouped by study in the `studies` array, in the same order as the requested `study_ids`. Every requested study has one entry, even when it has no matches or has not been indexed. The `limit` is the maximum number of matches across all study groups.

```json theme={null}
{
  "studies": [
    {
      "study_id": "11111111-2222-3333-4444-555555555555",
      "index_status": "ready",
      "latest_report_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
      "indexed_report_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
      "results": [
        {
          "content_id": "report:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee:study_finding:finding-1-1",
          "content_type": "study_finding",
          "report_id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
          "report_generated_at": "2026-09-16T12:00:00Z",
          "research_period": null,
          "content": {
            "finding_id": "finding-1-1",
            "learning_goal_id": "goal-pricing",
            "heading": "Pricing perception",
            "content": "Participants compared the price with lower-cost alternatives.",
            "reference_ids": ["ref_1"]
          }
        }
      ]
    }
  ],
  "next_cursor": null,
  "generated_content_returned": false
}
```

Use each study group's `index_status` to check freshness:

| Status | Meaning |
| - | - |
| `ready` | `indexed_report_id` matches `latest_report_id`; results use the latest report. |
| `updating` | A store exists, but the latest report has not become the active index yet. Search may return results from `indexed_report_id` while the replacement is built. |
| `not_indexed` | No active report index exists for the study. |

Each study group includes `latest_report_id` and `indexed_report_id` when available, so clients can show progress without treating an existing but stale store as current. A `not_indexed` study has an empty `results` array; this is distinct from an indexed study with no matches.

<Note>
  `limit` accepts 1–50. When `next_cursor` is non-null, pass it back with the same query, filters, and limit. Continue until it is null. The final page can be empty. Study access and current indexed records are checked on every page.
</Note>

## Ask across your research

Use the same study and date filters with `POST /api/public/v1/research/answer/` when you need a concise answer rather than raw records:

```sh theme={null}
curl --request POST \
  --url https://api.userintuition.ai/api/public/v1/research/answer/ \
  --header "Authorization: Bearer $USERINTUITION_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "question": "What concerns did participants raise about pricing?",
    "filters": {"study_ids": ["11111111-2222-3333-4444-555555555555"]}
  }'
```

The response has `answer` text with numbered references such as `[1]`, `citations[]` with canonical `content_id`, `study_id`, `content_type`, `report_id`, and optional `interview_id`, plus per-study index status. `insufficient_evidence` is true when the indexed records do not support an answer. Generated sentences are not verbatim interview quotes; inspect the cited record and interview before quoting a participant.

To inspect source evidence, resolve a finding's `reference_ids` through `GET /api/public/v1/studies/{study_id}/report?view=references`, then use the reference's `interview_id` with the interview API. Participant-response results include their public `interview_id` both on the result and in `content` when it can be resolved. Use that value with `GET /api/public/v1/interviews/{interview_id}`. Interview messages are paged; follow `next_message_offset` to retrieve later passages.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.