# GET /v1/catalogue:search

**Service:** Search  
**Operation:** `SearchService_SearchCatalogue`

Searches products, kits, and flashings by text query and returns one ranked list of minimal hits, most relevant first. Every whitespace- separated word in the query must match — against an entry's name, its category, a material, or a product attribute value (for example an Item Code). Fetch full detail with GetProduct, GetKit, or GetFlashing using the hit's id. Result order is relevance-based and may change between requests; it is not a stable contract.

This operation is in preview and not yet covered by the compatibility guarantees (see Versioning in the API conventions). Known limitations today: a page-by-page walk of a large result set can drop or repeat a row between pages, so fetch one large page when completeness matters; and a flashing hit's id cannot yet be passed to GetFlashing (see the hit's id field).

## Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `query` | query | string | no | The text to search for. Every whitespace-separated word must match. |
| `pageSize` | query | integer | no | Maximum number of hits to return per page. 0 uses the server default; the server may cap the value. |
| `pageToken` | query | string | no | Opaque page token from a previous response, used to fetch the next page. A token is bound to the query it was minted for. |
| `fields` | query | string | no | Comma-separated response fields to include, using camelCase JSON names (e.g. `orderId,total.amountMicros`). Dot paths reach into nested objects and map transparently across arrays. Paths are relative to the resource, not the response envelope; envelope keys like `nextPageToken` are always preserved. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Unknown names are silently ignored. Takes precedence over `excludeFields` when both are provided. |
| `excludeFields` | query | string | no | Comma-separated response fields to exclude, using camelCase JSON names. Dot paths and array-transparency work the same as `fields`. Paths are relative to the resource, not the response envelope. Only 2xx JSON responses are filtered; error bodies pass through unmodified. Ignored when `fields` is also provided. |

## Responses

| Status | Schema | Description |
| --- | --- | --- |
| 200 | `SearchCatalogueResponse` | A successful response. |
| 400 | `Error` | The request was rejected because it was malformed — for example an empty query or an unusable page token. The body is a validation-failure envelope: an overall type and message and one entry per problem (each with a stable code, a message, and a param pointing at the offending parameter). |
| 401 | `Error` | Authentication failed: the bearer token is missing, invalid, or expired. |
| 403 | `Error` | The token is valid but does not permit this action, or the resource belongs to a company the token cannot act for. The error type is permission_denied. |
| 429 | `Error` | The request was throttled (rate_limited) or exceeded a size limit (resource_exhausted). When throttled, the Retry-After header says how many seconds to wait before retrying; a resource_exhausted request will fail the same way if retried unchanged. |
| default | `Error` | Any other error. The body is the same error envelope every error uses: a short stable type identifying the kind of failure (for example "rate_limited" or "internal"), a human-readable message, and the request's idempotency key echoed back when one was supplied. |

## Returns

`SearchCatalogueResponse`

| Field | Type | Description |
| --- | --- | --- |
| `hits` | CatalogueSearchHit[] | The hits in this page. |
| `hits.id` | string | The entry's unique id. The prefix always agrees with `type`. A `prod_` id drills in with GetProduct and a `kit_` id with GetKit. KNOWN LIMITATION: a `flashing_` id is the flashing-family id and is NOT currently accepted by GetFlashing (which takes the fronting `flashtpl_` template id); flashing hits are therefore not drillable yet. Treat a flashing hit as name-only for now. |
| `hits.type` | CatalogueEntryType | What kind of catalogue entry this hit refers to. The kind of catalogue entry a search hit refers to. One of: CATALOGUE_ENTRY_TYPE_UNSPECIFIED, CATALOGUE_ENTRY_TYPE_PRODUCT, CATALOGUE_ENTRY_TYPE_KIT, CATALOGUE_ENTRY_TYPE_FLASHING. |
| `hits.name` | string | The entry's display name. |
| `hits.categoryId` | string | The id of the entry's category. Unset for flashings. |
| `hits.categoryName` | string | The display name of the entry's category. Unset for flashings. |
| `nextPageToken` | string | Token to pass as `pageToken` to fetch the next page; empty when there are no more results. |

---

Source: https://developer.factory.app/reference/search/search-catalogue · Factory Sales API v1
