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

# Search Memories & Documents in Project

> Run document search and memory search together in a single call

```
POST /openapi/memorylake/api/v1/projects/{id}/search
```

Searches across everything the project knows — both the ingested document content and the accumulated conversation memories — and returns the matches grouped by source. A single query surfaces the full picture, which is what you typically want in a chat assistant that grounds answers on documents **and** personalizes them with memories.

<Note>
  Items in `documents` and `memories` have the same shapes as [Search Documents](/features/memorylake/api-reference/memories/search-documents) and [Search Memories](/features/memorylake/api-reference/memories/search-memories) respectively — the relevant request knobs (`top_n`, `threshold`) carry the same meaning here.
</Note>

<Note>
  **Permission required:** [`project:search`](/features/team-collaboration/permission-reference#search-across-a-project-api-only) · `instance`
</Note>

### Path Parameters

<ParamField path="id" type="string" required>
  Project ID
</ParamField>

### Request Body

<ParamField body="query" type="string" required>
  Natural-language search query. Used by both sub-searches.
</ParamField>

<ParamField body="user_id" type="string" required>
  User ID filter for the memory sub-search. Document search ignores this field.
</ParamField>

<ParamField body="top_n" type="integer" default="10">
  Maximum number of results to return, 1–1000. Applied to both document and memory matches — e.g. `top_n=10` yields up to 10 documents and up to 10 memories.
</ParamField>

<ParamField body="threshold" type="number" default="0.3">
  Minimum similarity score for memory results. Scores below this are filtered out. Does not apply to documents.
</ParamField>

<ParamField body="with_conflicts" type="boolean" default="false">
  Include conflict info on memory results.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST 'https://app.memorylake.ai/openapi/memorylake/api/v1/projects/proj-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6/search' \
    -H 'Authorization: Bearer sk_xxxxxx' \
    -H 'Content-Type: application/json' \
    -d '{
      "query": "What were the quarterly sales figures in 2024?",
      "user_id": "user-abc123",
      "top_n": 10,
      "threshold": 0.3
    }'
  ```
</RequestExample>

### Response

<ResponseField name="data" type="object">
  <Expandable title="Combined search result">
    <ResponseField name="documents" type="array">
      Document search results. Each item is a discriminated union — `type` decides which variant-only fields are present and which sub-field of `highlight` is populated. Click to expand the full per-item shape.

      <Expandable title="Document result item">
        <ResponseField name="type" type="string" required>
          Discriminator. One of `paragraph`, `table`, or `figure`.
        </ResponseField>

        <ResponseField name="document_id" type="string">Document ID</ResponseField>
        <ResponseField name="document_name" type="string">Document file name, e.g. `report_2024.xlsx`</ResponseField>

        <ResponseField name="source_document" type="object">
          Source file info.

          <Expandable title="source_document properties">
            <ResponseField name="file_name" type="string">Original file name</ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="highlight" type="object">
          Matched content. The object always has the same three optional fields below — exactly one is populated, selected by the parent item's `type`.

          <Expandable title="highlight properties">
            <ResponseField name="chunks" type="Chunk[]">
              Populated when `type=paragraph`. Matched text spans, in document order. Absent otherwise.

              <Expandable title="Chunk properties">
                <ResponseField name="text" type="string">Plain-text snippet of the match</ResponseField>
                <ResponseField name="range" type="string">Location hint (e.g. page number `p12`, or a cell range for workbook paragraphs)</ResponseField>
              </Expandable>
            </ResponseField>

            <ResponseField name="inner_tables" type="InnerTable[]">
              Populated when `type=table`. Matched sub-tables within the source table region. Absent otherwise.

              <Expandable title="InnerTable properties">
                <ResponseField name="id" type="string">Inner table ID</ResponseField>
                <ResponseField name="data_range" type="string">Cell range covered, e.g. `A1:D50`</ResponseField>
                <ResponseField name="num_rows" type="integer">Number of data rows</ResponseField>
                <ResponseField name="persist_path" type="string">Internal storage path of the materialized table</ResponseField>

                <ResponseField name="columns" type="TableColumn[]">
                  Column descriptors.

                  <Expandable title="TableColumn properties">
                    <ResponseField name="id" type="string">Column ID</ResponseField>
                    <ResponseField name="name" type="string">Column header name</ResponseField>
                    <ResponseField name="data_type" type="string">Inferred data type (e.g. `string`, `number`, `date`)</ResponseField>
                    <ResponseField name="range" type="string">Column cell range</ResponseField>
                    <ResponseField name="count" type="integer">Non-null value count</ResponseField>
                    <ResponseField name="null_count" type="integer">Null value count</ResponseField>
                    <ResponseField name="approx_ndv" type="integer">Approximate number of distinct values</ResponseField>
                    <ResponseField name="min_value" type="string">Minimum value (string-encoded)</ResponseField>
                    <ResponseField name="max_value" type="string">Maximum value (string-encoded)</ResponseField>
                    <ResponseField name="examples" type="object[]">Sample raw values from the column</ResponseField>
                    <ResponseField name="display_examples" type="object[]">Sample formatted/display values</ResponseField>
                    <ResponseField name="semantic_comment" type="string">Model-inferred semantic comment for the column</ResponseField>
                    <ResponseField name="has_hierarchy" type="boolean">Whether the column participates in a row hierarchy</ResponseField>
                  </Expandable>
                </ResponseField>
              </Expandable>
            </ResponseField>

            <ResponseField name="figure" type="object">
              Populated when `type=figure`. The matched figure descriptor. Absent otherwise.

              <Expandable title="figure properties">
                <ResponseField name="caption" type="string">Original figure caption</ResponseField>
                <ResponseField name="text" type="string">OCR / extracted text inside the figure</ResponseField>
                <ResponseField name="summary_text" type="string">Model-generated summary of the figure</ResponseField>
                <ResponseField name="prequestion_list" type="string[]">Pre-generated questions the figure can answer</ResponseField>
                <ResponseField name="persist_path" type="string">Internal storage path of the figure asset</ResponseField>
              </Expandable>
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="paragraph_block_id" type="string">**Only when `type=paragraph`.** Paragraph block ID inside the document.</ResponseField>
        <ResponseField name="table_id" type="string">**Only when `type=table`.** Table entity ID.</ResponseField>
        <ResponseField name="title" type="string">**Only when `type=table`.** Table title.</ResponseField>
        <ResponseField name="footnote" type="string">**Only when `type=table`.** Table footnote.</ResponseField>
        <ResponseField name="sheet_name" type="string">**Only when `type=table`.** Worksheet name (workbook tables).</ResponseField>
        <ResponseField name="semantic_sheet_name" type="string">**Only when `type=table`.** Model-inferred semantic name for the worksheet.</ResponseField>
        <ResponseField name="semantic_comment" type="string">**Only when `type=table`.** Model-inferred semantic comment for the worksheet.</ResponseField>
        <ResponseField name="table_region_info" type="string">**Only when `type=table`.** Table region location, e.g. `A1:D50`.</ResponseField>
        <ResponseField name="figure_id" type="integer">**Only when `type=figure`.** Figure numeric ID.</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="memories" type="array">
      Memory search results. Same shape as [Search Memories](/features/memorylake/api-reference/memories/search-memories).

      <Expandable title="Memory result item">
        <ResponseField name="id" type="string">Memory ID</ResponseField>
        <ResponseField name="content" type="string">Memory content</ResponseField>
        <ResponseField name="user_id" type="string">Associated user ID</ResponseField>
        <ResponseField name="expired" type="boolean">Whether this memory has expired</ResponseField>
        <ResponseField name="has_unresolved_conflict" type="boolean">Whether this memory has an unresolved conflict (only meaningful when `with_conflicts=true`)</ResponseField>
        <ResponseField name="created_at" type="string">Creation timestamp (ISO 8601)</ResponseField>
        <ResponseField name="updated_at" type="string">Last update timestamp (ISO 8601)</ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseExample>
  ```json Success (200) theme={null}
  {
    "success": true,
    "message": "Operation completed successfully",
    "data": {
      "documents": [
        {
          "type": "paragraph",
          "document_id": "doc-123",
          "document_name": "report_2024.pdf",
          "paragraph_block_id": "blk-456",
          "highlight": {
            "chunks": [
              { "text": "Q1 2024 sales reached $2.5M...", "range": "p12" }
            ]
          },
          "source_document": { "file_name": "report_2024.pdf" }
        },
        {
          "type": "table",
          "document_id": "doc-789",
          "document_name": "sales_data.xlsx",
          "table_id": "tbl-001",
          "title": "Quarterly Sales Summary",
          "sheet_name": "Sheet1",
          "semantic_sheet_name": "2024 Quarterly Sales",
          "table_region_info": "A1:D50",
          "highlight": {
            "inner_tables": [
              {
                "id": "itbl-001",
                "data_range": "A1:D50",
                "num_rows": 49,
                "persist_path": "tables/doc-789/itbl-001",
                "columns": [
                  {
                    "id": "col-1",
                    "name": "Quarter",
                    "data_type": "string",
                    "range": "A2:A50",
                    "count": 49,
                    "null_count": 0,
                    "approx_ndv": 4,
                    "examples": [{ "v": "Q1" }, { "v": "Q2" }],
                    "display_examples": [{ "v": "Q1" }, { "v": "Q2" }]
                  },
                  {
                    "id": "col-2",
                    "name": "Revenue",
                    "data_type": "number",
                    "range": "B2:B50",
                    "min_value": "1200000",
                    "max_value": "3100000"
                  }
                ]
              }
            ]
          },
          "source_document": { "file_name": "sales_data.xlsx" }
        },
        {
          "type": "figure",
          "document_id": "doc-456",
          "document_name": "report_2024.pdf",
          "figure_id": 7,
          "highlight": {
            "figure": {
              "caption": "Figure 7. Quarterly revenue trend, 2024",
              "text": "Q1 $2.5M  Q2 $2.8M  Q3 $3.0M  Q4 $3.1M",
              "summary_text": "Bar chart showing steady quarterly revenue growth across 2024.",
              "prequestion_list": [
                "Which quarter had the highest revenue in 2024?",
                "What was the revenue trend across 2024?"
              ],
              "persist_path": "figures/doc-456/fig-7.png"
            }
          },
          "source_document": { "file_name": "report_2024.pdf" }
        }
      ],
      "memories": [
        {
          "id": "mem-123",
          "content": "User prefers Hangzhou cuisine restaurants",
          "user_id": "user-abc123",
          "expired": false,
          "has_unresolved_conflict": false,
          "created_at": "2024-01-15T10:00:00Z",
          "updated_at": "2024-01-15T10:00:00Z"
        }
      ]
    }
  }
  ```
</ResponseExample>

<Tip>
  Either list can be empty if no matches cross the threshold. Treat `documents` and `memories` independently — they're just two lookups returned together for convenience.
</Tip>
