---
title: "Get search history"
method: GET
path: "/search"
tags: ["Semantic Search"]
---

# Get search history

`GET /search`

Retrieve the authenticated user's persisted search history.

Returns searches the user owns along with searches shared with them,
scoped to the caller's organization. Archived and deleted entries are
excluded. Citation references on this endpoint are returned as raw
identifier strings; use `GET /search/{searchId}` to fetch a single
search with its citations fully expanded.

Pagination defaults to `page=1, limit=20` (maximum `limit` is 100).
Results are sorted by most recent activity by default.

## Query parameters

- `page` integer
- `limit` integer
- `sortBy` 'createdAt' | 'lastActivityAt' | 'title'
- `sortOrder` 'asc' | 'desc'
- `search` string
- `shared` 'true' | 'false' | '1' | '0'
- `startDate` string, date-time
- `endDate` string, date-time

## Response `200`

Persisted search history plus pagination, applied/available filter
metadata, and a request-scoped `meta` block.

- SemanticSearchHistoryResponse — Envelope returned by `GET /search`. The handler runs `find()` plus `countDocuments()` in parallel and assembles `{ searchHistory, pagination, filters, meta }` (es_controller.ts:3925-3973).
  - `searchHistory` SemanticSearchHistoryItem[], required
    - `_id` string, objectId, required
    - `__v` integer, required
    - `query` string, required
    - `limit` integer, required
    - `orgId` string, objectId, required
    - `userId` string, objectId, required
    - `citationIds` string[], required
    - `records` object, required — Map of source-record id (or `_key`) to `JSON.stringify(<record>)`. Clients must `JSON.parse` each value to recover the underlying record object. Populated at write-time in the POST `/search` handler.
    - `isShared` boolean, required
    - `shareLink` string — Set once the search has been shared via `/search/{searchId}/share`.
    - `sharedWith` PersistedSemanticSearchSharedWithEntry[], required
      - `userId` string, objectId, required
      - `accessLevel` 'read' | 'write', required
    - `isArchived` boolean, required
    - `archivedBy` string, objectId, nullable — User ID of the last user who archived this row, or `null` after an unarchive cleared the archive state. Absent on rows that have never been archived.
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required
  - `pagination` SemanticSearchHistoryPagination, required — Pagination block emitted by `buildPaginationMetadata` (utils.ts:417). `totalPages` is `Math.ceil(totalCount / limit)`, so an empty result has `totalPages: 0`, not `1`.
    - `page` integer, required
    - `limit` integer, required
    - `totalCount` integer, required
    - `totalPages` integer, required
    - `hasNextPage` boolean, required
    - `hasPrevPage` boolean, required
  - `filters` SemanticSearchHistoryFilters, required
    - `applied` SemanticSearchHistoryFiltersApplied, required — Echo of which filters the caller actually supplied, built by `buildFiltersMetadata` (utils.ts:430-486). `page` and `limit` always appear because they are normalised to defaults before being recorded, so `filters` is never empty and `values` always contains at least `{ page, limit }`. Other keys appear only when the matching query param was non-empty (or, for `dateRange`, when `createdAt` was set on the Mongo filter). `values` keys are scalar strings rather than typed primitives (`'true'`/`'false'`, `'5'`, etc.) because they are passed through from `req.query` as Express parsed them — only `page` and `limit` are coerced to integers via `safeParsePagination`.
      - `filters` string[], required
      - `values` object, required
        - `page` integer
        - `limit` integer
        - `search` string
        - `shared` string
        - `tags` string
        - `minMessages` string
        - `sortBy` string
        - `sortOrder` string
        - `startDate` string
        - `endDate` string
        - `messageType` string
        - `dateRange` SemanticSearchHistoryAppliedDateRange — Echoed back only when the caller passed `startDate` and/or `endDate`. Each bound is an ISO 8601 string when set; the field is absent when the corresponding query param was omitted (utils.ts:480-486 reads `appliedFilters.createdAt.$gte?.toISOString()` directly, so missing bounds become `undefined` and drop out of the JSON).
          - `start` string, date-time
          - `end` string, date-time
    - `available` SemanticSearchHistoryFiltersAvailable, required — Catalogue of filters the endpoint supports, plus their current values and `applied` flags. Built by `buildFiltersMetadata` (utils.ts:430-624).
      - `shared` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `tags` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `minMessages` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `search` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
        - `type` string
        - `values` string[]
        - `description` string, required
        - `current` string, nullable, required
        - `applied` boolean, required
      - `pagination` object, required
        - `page` SemanticSearchHistoryPaginationField, required
          - `type` string, required
          - `current` integer, required
          - `min` integer, required
          - `max` integer, required
          - `default` integer, required
          - `description` string, required
          - `applied` boolean, required
        - `limit` SemanticSearchHistoryPaginationField, required
          - `type` string, required
          - `current` integer, required
          - `min` integer, required
          - `max` integer, required
          - `default` integer, required
          - `description` string, required
          - `applied` boolean, required
      - `sorting` object, required
        - `sortBy` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
        - `sortOrder` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
      - `dateFilters` object, required
        - `dateRange` SemanticSearchHistoryDateRange, required
          - `type` string, required
          - `description` string, required
          - `format` string, required
          - `current` object, required
            - `start` string, nullable, required
            - `end` string, nullable, required
          - `applied` boolean, required
      - `messageFilters` object, required
        - `messageType` SemanticSearchHistoryFilterToggle, required — Generic "filter X is available, current value is Y" block used for `shared`, `tags`, `minMessages`, `search`, and `messageType`. Either `type` (free-form value) or `values` (enum of allowed strings) is present, not both. `current` is the caller-supplied value passed through from `req.query`, hence string-or-null even when `type` is `'number'`.
          - `type` string
          - `values` string[]
          - `description` string, required
          - `current` string, nullable, required
          - `applied` boolean, required
      - `sortingMessages` object, required
        - `sortBy` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
        - `sortOrder` SemanticSearchHistorySortField, required — Used for `available.sorting.{sortBy,sortOrder}` and `available.sortingMessages.{sortBy,sortOrder}`. The `applied` flag is present on `sorting.*` and absent on `sortingMessages.*`, so it is optional here.
          - `values` string[], required
          - `default` string, required
          - `description` string, required
          - `current` string, required
          - `applied` boolean
  - `meta` SemanticSearchHistoryMeta, required — `requestId` comes from `req.context?.requestId` and is omitted from the JSON when upstream middleware did not set it.
    - `requestId` string
    - `timestamp` string, date-time, required
    - `duration` integer, required

## Other responses

- `400` — Invalid request, raised when a query parameter fails validation — for example a malformed `startDate` / `endDate`, a `search` value over 1000 characters, or a query value that trips the XSS guard.
- `401` — Missing or invalid bearer token.
- `403` — Bearer token lacks the `semantic:read` scope.
- `500` — Server error. Possible causes: - Explicit `InternalServerError` or any other 500 `BaseError` thrown by the handler. - Non-`BaseError` exception caught by the global error middleware. - Response serializer fallback.

---

[API](https://skmtc.net/pipeshub-ai/apis/pipeshub-api.md) · [All operations](https://skmtc.net/pipeshub-ai/apis/pipeshub-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/pipeshub-ai/pipeshub-api/versions/abd27cfefc73/schema)
