---
title: "Search Query"
method: POST
path: "/search/query"
tags: ["Search"]
---

# Search Query

`POST /search/query`

Run a search query. Provide exactly one query source: simple_filters, filters, parsed_query, or search_id. For pagination, pass cursor alone.

## Headers

- `x-api-key` string, nullable

## Request body

- SearchQueryRequest — Unified search query request — replaces both /start-filter-search and /browse.
  - `simple_filters` object, nullable — MongoDB-style filters; the API translates them to DSL.
  - `filters` object, nullable — Raw OpenSearch DSL filters.
  - `parsed_query` object, nullable — Structured filter set returned by a previous search.
  - `search_id` string, nullable — Search history ID returned by a previous search. Replays only the query shape; pass exclusions again on this request if they should apply.
  - `query` string, nullable — Natural-language query. Mutually exclusive with simple_filters / filters / parsed_query / search_id. People-mode only.
  - `cursor` string, nullable — Opaque pagination cursor returned by a previous response.
  - `mode` 'people' | 'company' — Search mode; inferred from DB when using `search_id`.
  - `page_size` integer — Maximum number of results per page (1-100). Pages may contain fewer rows while more results remain (e.g. with exclusion filtering); rely on `has_more`/`next_cursor`, never on page fullness.
  - `max_results` integer — Maximum number of results to return across pages.
  - `exclude_public_ids` string[], nullable — People-mode inline identifiers to exclude from results, applied as a post-filter. Accepts LinkedIn public IDs or profile URLs. For company searches, use `exclude_entity_ids`. Max 1000.
  - `exclude_entity_ids` string[], nullable — Inline identifiers to exclude from results, applied as a post-filter. People mode: LinkedIn public IDs or profile URLs. Company mode: numeric LinkedIn company IDs, company URLs/slugs, or exact website domains (values that resolve to no or multiple companies are ignored). Max 1000.
  - `exclude_list_ids` string[], nullable — Saved exclusion-list IDs to apply as a post-filter. Each list's entity type must match the search mode (person lists for people searches, company lists for company searches). Max 5 (10 for organizations with extended exclusion limits).
  - `location_expansion_enabled` boolean — Expand the parsed location filter to nearby areas via PostGIS radius. People-mode `query` branch only.
  - `location_expansion_radius_miles` integer — Radius (miles) for PostGIS location expansion. Ignored when expansion is disabled.

## Response `200`

Successful Response

- FilterSearchResponse — Response for a completed filter search.
  - `search_id` string, nullable — Search history ID returned by a previous search. Replays only the query shape; pass exclusions again on this request if they should apply.
  - `resource_handle_id` string — Legacy export handle. Empty for company direct-filter mode.
  - `csv_download_url` string, nullable — Signed URL to download results as CSV.
  - `json_download_url` string, nullable — Signed URL to download results as JSON.
  - `next_cursor` string, nullable — Cursor to fetch the next page; null when exhausted.
  - `cursor_expires_in_seconds` integer, nullable — Seconds until `next_cursor` expires.
  - `request_duration_ms` integer, nullable — Server-side request duration in milliseconds.
  - `has_more` boolean — True when another page is available via `next_cursor`. Always continue via the cursor; a short or empty page does NOT mean the results are exhausted.
  - `page_size` integer, nullable — Maximum number of results per page (1-100). Pages may contain fewer rows while more results remain (e.g. with exclusion filtering); rely on `has_more`/`next_cursor`, never on page fullness.
  - `page_count` integer, nullable — Number of results in this response page. May be less than `page_size` (down to 0) while `has_more` is true, e.g. when exclusion filtering is active.
  - `page_number` integer, nullable — 1-based page number (company pagination).
  - `total_pages` integer, nullable — Final total page count; omitted while `has_more` is true.
  - `max_pages` integer, nullable — Upper bound on pages based on max_results and page_size.
  - `remaining_results` integer, nullable — Rows still available under max_results after this page.
  - `download_expires_in_seconds` integer, nullable — Seconds until the download URLs expire.
  - `total_results` integer, required — Rows returned so far (cumulative for company pagination).
  - `total_available` integer, nullable — Total OpenSearch matches across pages (capped at 50000); people-mode only. Pre-exclusion: exclusion filtering does not reduce this count.
  - `exported_count` integer — Legacy export count; always 0 for company direct-filter mode.
  - `results` object[] — Rows returned for the current page.
  - `parsed_query` object, nullable — Structured filter set echoed back; round-trippable into a follow-up request.
  - `natural_language_query` string, nullable — Original natural-language query echoed verbatim, if any.

## Other responses

- `400` — Request was rejected by the route's validation rules.
- `401` — Missing or invalid API key.
- `402` — Insufficient credits or no active subscription for this organization.
- `403` — Forwarded user_id does not belong to caller's organization.
- `404` — Search task or export file not found.
- `409` — Export workflow already running for this search.
- `422` — Request body failed validation.
- `429` — Rate limit exceeded.
- `500` — Unexpected server error. Retry with backoff.
- `502` — Upstream search backend returned an error.
- `503` — Search backend is not configured or unavailable.
- `504` — Upstream search backend timed out.

---

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