---
title: "GET /search/query"
method: GET
path: "/search/query"
tags: ["search"]
---

# GET /search/query

`GET /search/query`

Execute a structured search query against the local encrypted search index.
Returns HTTP 423 if the encryption session is locked.

ADR-008 wire change: `total`/`hasMore` are no longer top-level siblings of
the envelope — they are folded INTO the `data` payload alongside the renamed
`items` array (`SearchQueryResultDto`). The response is the canonical
`ApiEnvelope<SearchQueryResultDto>` (`{ data: { items, total, hasMore }, ts }`).

## Query parameters

- `query` string, required
- `operator` string, nullable
- `timePreset` string, nullable
- `fromMs` integer, nullable
- `toMs` integer, nullable
- `contentTypes` string, nullable
- `extensions` string, nullable
- `sourceDevices` string, nullable
- `limit` integer
- `offset` integer

## Response `200`

Search results page

- SearchQueryEnvelope — Canonical success envelope: `{ "data": T, "ts": <unix millis i64> }`. `ts` is `chrono::Utc::now().timestamp_millis()`, set in the webserver handler via [`ApiEnvelope::now`] (the contract carries only the type + the clock helper, not a hard dependency on when the handler reads the clock). `rename_all = "camelCase"` is a no-op for the single-word fields here but is declared for forward-compat. IMPORTANT (utoipa v4): every concrete `ApiEnvelope<X>` that needs a named OpenAPI component is declared in the `#[aliases(...)]` block below. Add a new alias line whenever a new payload type needs enveloping. NEVER register the bare `ApiEnvelope` in `components(schemas(...))` — utoipa errors on a bare generic, and an un-aliased generic inlines an anonymous schema.
  - `data` SearchQueryResultDto, required — Folded payload for `GET /search/query` (ADR-008 §0.1). The current handler returns `total` and `hasMore` as top-level siblings of the `{data,ts}` envelope (`data` is the items array). This DTO folds those siblings INTO the payload (renaming `data` → `items`) so the endpoint can return `ApiEnvelope<SearchQueryResultDto>` with no bespoke wrapper. P1 only defines the type; the handler is rewired in P2.
    - `hasMore` boolean, required
    - `items` SearchResultDto[], required
      - `activeTimeMs` integer, required
      - `contentType` string, required
      - `entryId` string, required
      - `fileExtensions` string[], required
      - `mimeType` string, required
      - `textPreview` string, nullable
    - `total` integer, required
  - `ts` integer, required — Server time when the response was built (unix epoch milliseconds).

## Other responses

- `400` — Invalid or malformed query
- `423` — Encryption session is locked
- `500` — Internal server error
- `503` — Search index not ready or unavailable

## Changes

- **2026-06-25** `318957db0286` — 1 info
  - added the new optional `query` request parameter `sourceDevices`
- **2026-06-02** `e7038123d268` — 5 breaking, 5 warning
  - removed the required property `data/items/items/fileNames` from the response with the `200` status
  - removed the required property `data/items/items/filePaths` from the response with the `200` status
  - removed the required property `data/items/items/linkUrls` from the response with the `200` status
  - removed the required property `data/items/items/tags` from the response with the `200` status
  - …6 more

[Change history](https://skmtc.dev/uniclipboard/apis/uniclipboard-daemon-api/changes/search/query/get.md)

---

[API](https://skmtc.dev/uniclipboard/apis/uniclipboard-daemon-api.md) · [All operations](https://skmtc.dev/uniclipboard/apis/uniclipboard-daemon-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/uniclipboard/uniclipboard-daemon-api/revisions/95d72e8dcd2f/schema)
