> For the complete documentation index, see [llms.txt](https://docs.partssource.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.partssource.com/api/core-concepts/search-query-language.md).

# Search Query Language

Query data using a structured search language on GET search endpoints

Several PartsSource GET search endpoints accept a structured query via the `q` query parameter. This language supports exact matching, substring matching, numeric and date comparisons, negation, and boolean logic — giving you precise control over which records are returned.

{% hint style="info" %}
Each API defines its own searchable fields. See the field reference for your API:

* [Customer API — Searchable Fields](https://github.com/PartsSourceInc/gitbook-documentation/blob/main/customer-api/searchable-fields.md)
  {% endhint %}

***

## Quick Start

Search for manufacturers by name:

```bash
curl -G "https://api.partssource.com/customer/api/manufacturers/search" \
  -H "Authorization: Bearer <token>" \
  --data-urlencode 'q=name~"philips"' \
  -d "limit=20"
```

Response:

```json
{
  "data": {
    "items": [
      { "manufacturerId": 26799, "name": "Philips Healthcare" }
    ],
    "pagination": {
      "total": 1,
      "limit": 20,
      "offset": 0,
      "hasMore": false
    }
  }
}
```

***

## Query Syntax

A query consists of one or more **clauses** joined by `AND`. Each clause targets a single field.

```
<clause> [AND <clause>]*
```

A **clause** has the form:

```
[-]<field><operator><value>
```

| Component      | Description                                                         |
| -------------- | ------------------------------------------------------------------- |
| `-` (optional) | Negation prefix. Excludes matching records.                         |
| `field`        | A searchable field name defined for the endpoint. Case-insensitive. |
| `operator`     | One of `:`, `~`, `>`, `<`, `>=`, `<=`.                              |
| `value`        | A quoted string (`"..."`) or unquoted numeric/keyword value.        |

***

## Operators

| Operator | Name                  | Description                                                               | Applies to                       |
| -------- | --------------------- | ------------------------------------------------------------------------- | -------------------------------- |
| `:`      | Exact match           | Case-insensitive equality. For String fields, matches the complete value. | Token, String, Numeric, DateTime |
| `~`      | Substring             | Case-insensitive substring match. Minimum 3 characters required.          | String only                      |
| `>`      | Greater than          | Strictly greater than the given value.                                    | Numeric, DateTime                |
| `<`      | Less than             | Strictly less than the given value.                                       | Numeric, DateTime                |
| `>=`     | Greater than or equal | Greater than or equal to the given value.                                 | Numeric, DateTime                |
| `<=`     | Less than or equal    | Less than or equal to the given value.                                    | Numeric, DateTime                |

### Operator Compatibility by Field Type

| Field Type | `:` | `~` | `>` `<` `>=` `<=` |
| ---------- | --- | --- | ----------------- |
| Token      | Yes | No  | No                |
| String     | Yes | Yes | No                |
| Numeric    | Yes | No  | Yes               |
| DateTime   | Yes | No  | Yes               |

Using an operator incompatible with a field's type returns a `400 Bad Request` error.

***

## Field Types

Each searchable field has one of four types. The type determines which operators are valid and how values are interpreted.

### Token

Exact-match identifiers, statuses, and enum values. Compared case-insensitively. Not searchable by substring.

```
status:"Pending"
active:"Y"
```

### String

Free-text fields like names, descriptions, and email addresses. Support both exact match (`:`) and substring match (`~`). All comparisons are case-insensitive.

```
email:"john@example.com"       # exact match
firstName~"joh"                 # substring match (min 3 chars)
companyName:"Acme Corp"         # exact match
```

### Numeric

Integer or decimal fields like IDs and amounts. Support exact match and range comparisons. Values must not be quoted.

```
companyId:500                   # exact
orderId>10000                   # range
```

### DateTime

Date and timestamp fields. Support exact match and range comparisons. Values use ISO 8601 format and must be quoted.

```
createdDate:"2026-01-15"                    # exact date
createdDate>="2026-01-01"                   # on or after
createdDate<"2026-02-01"                    # before
```

***

## Boolean Logic

Multiple clauses must be joined with the `AND` keyword.

```
status:"Pending" AND companyId:500
```

### Restrictions

* **Maximum 10 clauses** per query.
* Only `AND` logic is supported.
* **No parentheses** for grouping or operator precedence.

***

## Negation

Prefix a clause with `-` to exclude matching records.

```
-status:"Completed"                          # everything except Completed
-email~"test"                                # exclude test emails
```

Negation inverts the clause. When combined with `AND`, all negated conditions are excluded.

***

## Null Checks

Use the `null` keyword (case-insensitive) as a value with the exact-match operator to test for field presence.

```
email:null                                   # field is null / missing
-email:null                                  # field is not null / exists
```

***

## Value Quoting Rules

| Value type      | Quoting                              | Examples                         |
| --------------- | ------------------------------------ | -------------------------------- |
| String values   | **Required** — wrap in double quotes | `email:"john@example.com"`       |
| Numeric values  | **Not required** — bare numbers      | `companyId:500`                  |
| DateTime values | **Required** — wrap in double quotes | `createdDate:"2026-01-15"`       |
| Null keyword    | **Not quoted**                       | `email:null`                     |
| Embedded quotes | Escape with backslash                | `description:"called \"Title\""` |

***

## Pagination and Sorting

GET search endpoints use **query parameter pagination** rather than a request body.

```
GET /{resource}/search?q=<query>&limit=<int>&offset=<int>&sortBy=<field>&sortDir=<asc|desc>
```

| Parameter | Required | Default          | Constraints                                                   |
| --------- | -------- | ---------------- | ------------------------------------------------------------- |
| `q`       | No       | —                | Valid search query string. When omitted, returns all results. |
| `limit`   | No       | `50`             | 1–100                                                         |
| `offset`  | No       | `0`              | >= 0                                                          |
| `sortBy`  | No       | Resource default | Must be a valid sort field for the resource                   |
| `sortDir` | No       | `Asc`            | `Asc` or `Desc`                                               |

### Response Format

```json
{
  "data": {
    "items": [ ... ],
    "pagination": {
      "total": 142,
      "limit": 50,
      "offset": 0,
      "hasMore": true
    }
  }
}
```

{% hint style="info" %}
For general pagination patterns (navigating pages, performance tips, code examples), see [Pagination](/api/core-concepts/pagination.md).
{% endhint %}

***

## Error Responses

Parse errors are returned as `400 Bad Request` with an RFC 7807 problem details body.

### Unknown field

```json
{
  "type": "https://tools.ietf.org/html/rfc7807",
  "title": "Invalid search query",
  "status": 400,
  "detail": "Unknown field 'foo'. Valid fields: email, firstName, lastName, customerId, userName, companyName"
}
```

### Invalid operator for field type

```json
{
  "type": "https://tools.ietf.org/html/rfc7807",
  "title": "Invalid search query",
  "status": 400,
  "detail": "Operator '~' is not supported for Numeric field 'companyId'. Use ':' for exact match or '>', '<', '>=', '<=' for range."
}
```

### Substring too short

```json
{
  "type": "https://tools.ietf.org/html/rfc7807",
  "title": "Invalid search query",
  "status": 400,
  "detail": "Substring match '~' requires at least 3 characters. Got: 'ab'"
}
```

### Too many clauses

```json
{
  "type": "https://tools.ietf.org/html/rfc7807",
  "title": "Invalid search query",
  "status": 400,
  "detail": "Search query exceeds the maximum of 10 clauses."
}
```

***

## Examples

### Find manufacturer by exact name

```
GET /manufacturers/search?q=name:"Siemens Healthineers"
```

### Find manufacturers by name substring

```
GET /manufacturers/search?q=name~"philips"
```

### Paginate through manufacturer results with sorting

```
GET /manufacturers/search?q=name~"health"&limit=25&offset=0&sortBy=name&sortDir=Asc
```

### Find users by search query

```
GET /users/search?q=email~"@hospital.org"&limit=20
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.partssource.com/api/core-concepts/search-query-language.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
