# Search sales orders and quotes

```http
GET https://secure.yoprint.com/v2/api/store/{team_slug}/search/orders
```

- API version: v2
- Operation ID: `v2_public_search_orders_get`
- Section: Sales › [Search](https://developer.yoprint.com/reference/search.md)
- Web page: https://developer.yoprint.com/reference/search/v2-search-orders-get/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Finds sales orders and quotes by a word or number, for a search box or a picker. It returns at most 30 matches, with no paging, highest order number first.

The text in `q` matches anywhere inside ("contains") any of: the order number, the order name, the customer PO number, the customer's name, and every part of the shipping and billing addresses (label, street lines, city, state, country, postcode). Several words also match when each word is found in a different field, so `northwind 1188` finds Northwind Apparel's order with PO number `PO-1188`. Without `q`, you get the first 30 in the same order.

Send the same fields as query parameters with `GET`, or as a JSON body with `POST`. **To search quotes only**, send `quote=1` in the query string (`GET .../search/orders?q=northwind&quote=1`) or `"quote": true` in a `POST` body; `quote=0` or `false` gives sales orders only. `quote=true` in a query string is refused with 422.

Each result is the same order or quote object Get a sales order or quote returns, without `items`. Amounts come in two encodings:
- Thousandths, an older encoding: `calc_subtotal`, `calc_tax`, `calc_total`, and `paid_amount` (`270000` is 270.00). The `calc_*` fields count only invoiced amounts, so they are `0` on an order with no invoice.
- Decimal pairs: `order_item_cart_total` (the lines' value), `order_balance_due`, and `invoiced_total`. The amount is `value` ÷ 10^`dp` (`{"value": 2700000, "dp": 4}` is 270.00). Read `dp` every time.

For more than 30 results, or for filters, use the sales order and quote list operations.

## Permission

Needs permission to view orders. With "view all orders" you search every order; with "view own orders" only the orders you created or are assigned to.

## Business rules

- `q` and `query` are at most 255 characters.
- `customer_id` must be a customer id of this team.
- Searching is "contains" and ignores case. `%` and `_` are matched as plain characters.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.

## Query parameters

- `q` (string, optional): What to look for. Leave it out to list orders by order number. At most 255 characters. Example `northwind`.
- `query` (string, optional): Another name for `q`. `q` wins when both are sent. At most 255 characters.
- `customer_id` (string, optional): Only this customer's orders. A customer id.
- `quote` (integer, optional): `1` for quotes only, `0` for sales orders only. Leave it out for both. In the query string `true` and `false` are refused with 422; with `POST`, a JSON `true` or `false` works. One of: `0`, `1`. Example `1`.
- `hide_draft` (integer, optional): Does not hide drafts, despite its name. Don't use it; check `internal_status` in the results instead. Like `quote`, it takes `1` or `0` in the query string. One of: `0`, `1`. Example `0`.

## Request body

This operation takes no request body.

### Example request

```bash
curl 'https://secure.yoprint.com/v2/api/store/your-team/search/orders' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1'
```

## Response

`200` Successful response.

Fields:

- `data` (array of objects, required): At most 30 orders and quotes. Each is the same object Get a sales order or quote returns, without `items`; the main fields are listed here. At most 30 items.
  - Each item:
    - `approval_status` (string | null, optional)
    - `billing_address` (object | null, optional)
    - `calc_subtotal` (integer | number | string | null, optional): Invoiced subtotal: what has been invoiced so far, `0` until the order is invoiced. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
    - `calc_tax` (integer | number | string | null, optional): Invoiced tax, `0` until the order is invoiced. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
    - `calc_total` (integer | number | string | null, optional): Invoiced total, `0` until the order is invoiced. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/). For the value of the order's lines, read `order_item_cart_total`.
    - `created_at` (string (date-time) | null, optional)
    - `customer` (object | null, optional): The customer, with `id` and `name`.
    - `customer_id` (string | null, optional)
    - `customer_po_number` (string | null, optional)
    - `due_date` (string (date-time) | null, optional): Production due date.
    - `id` (string, optional): The order's id. Use it in the order operations.
    - `internal_status` (string | null, optional): `draft` or `published`. Null on orders from before drafts existed. One of: `"draft"`, `"published"`.
    - `invoiced_total` (decimal pair, optional): Total of the order's invoices. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1350000, "dp": 4 }` is 135.00). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
    - `is_draft` (boolean, optional): True when `mode` is `create`. Older field; prefer `internal_status`.
    - `is_quote` (boolean, optional): True for a quote. Same as `object_type` `quote`.
    - `is_rush` (boolean, optional)
    - `issue_date` (string (date-time) | null, optional)
    - `mode` (string, optional): `create`: a draft. `edit`: being edited. `view`: saved. One of: `"create"`, `"edit"`, `"view"`.
    - `name` (string | null, optional)
    - `object_type` (string, optional): What it is. Prefer this field. One of: `"sales_order"`, `"quote"`.
    - `order_balance_due` (decimal pair, optional): Invoiced total minus payments. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 850000, "dp": 4 }` is 85.00). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
    - `order_item_cart_total` (decimal pair, optional): The value of the order's lines, invoiced or not. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 2500000, "dp": 4 }` is 250.00). Read `dp` every time: it can differ between fields and records. Stored amounts usually have 4 decimal places; an order with no amount yet can come as `{ "value": 0, "dp": 0 }`. See https://developer.yoprint.com/concepts/money-and-quantities.md.
    - `paid_amount` (integer | number | string | null, optional): Payments received. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
    - `scoped_id` (string, optional): The order or quote number people see, such as `SO1001`. Not an id.
    - `shipping_address` (object | null, optional)
    - `status` (object | null, optional): That status, with its `label`.
    - `status_id` (string | null, optional): The order's status id in your team's statuses.
    - `trashed` (boolean, optional)
    - `type` (string, optional): The same thing in older words: `order` for a sales order. One of: `"order"`, `"quote"`.
    - `unique_key` (string, optional): The order's unique key (`ord_...`), for the operations that take one.
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": [
    {
      "approval_status": null,
      "billing_address": null,
      "calc_subtotal": 125000,
      "calc_tax": 10000,
      "calc_total": 135000,
      "created_at": "2026-11-03T09:30:00+00:00",
      "customer": {
        "id": "63KcENAAsKuipY",
        "is_external": false,
        "name": "Northwind Apparel",
        "tax_exempt": false
      },
      "customer_id": "63KcENAAsKuipY",
      "customer_po_number": "PO-1188",
      "due_date": "2026-11-14T00:00:00+00:00",
      "id": "V4keXwwxMQyXw7",
      "internal_status": "published",
      "invoiced_total": {
        "dp": 4,
        "value": 1350000
      },
      "is_draft": false,
      "is_quote": false,
      "is_rush": false,
      "issue_date": "2026-11-03T00:00:00+00:00",
      "mode": "view",
      "name": "Spring team shirts",
      "object_type": "sales_order",
      "order_balance_due": {
        "dp": 4,
        "value": 850000
      },
      "order_item_cart_total": {
        "dp": 4,
        "value": 1250000
      },
      "paid_amount": 50000,
      "scoped_id": "SO1001",
      "shipping_address": {
        "address1": "100 Example Street",
        "city": "Springfield",
        "country_code": "US",
        "id": "RNG2OuYC20YzXs",
        "label": "Head office",
        "postcode": "62701",
        "state_code": "IL"
      },
      "status": {
        "color": "#2196f3",
        "customer_label": "In Progress",
        "id": "52CuV8sWcDZLPm",
        "label": "In production",
        "position": 2,
        "role": "order",
        "trashed": false,
        "type": "in_progress"
      },
      "status_id": "52CuV8sWcDZLPm",
      "trashed": false,
      "type": "order",
      "unique_key": "ord_EXAMPLEuniqueKey"
    }
  ],
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
  - When: Your role can't view orders (`unauthorized`). Fix: Ask a team admin for permission to view orders.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: `q` is longer than 255 characters, `customer_id` is not a valid id, or `quote` or `hide_draft` is not a boolean. In a `GET` query string, `quote=true` is refused this way (`validation_failed`; `error.fields` names the field). Fix: In the query string send `quote=1` (quotes) or `quote=0` (sales orders). In a `POST` body, JSON `true` or `false` work.

## Notes

- Results have no relevance ranking: every match counts the same, sorted by order number as text, highest first. Past 9,999 orders that text order is uneven (`SO9999` comes before `SO010000`). Narrow the text if what you want is not in the first 30.
- Draft orders are included. Deleted orders are not.
- Quotes are searched with your order permissions.
- The whole text is matched as one phrase, and the first 5 different words are also matched one by one; words after the fifth are not.
- `hide_draft` does not hide drafts. It compares the order's status with one fixed status record that belongs to at most one team, so for almost every team it changes nothing. To leave drafts out, skip results whose `internal_status` is `draft` (or `mode` is `create`).
- Search results, Get order and the order lists share field names: `object_type` (`sales_order` or `quote`) is the same fact as `type` (`order` or `quote`) and `is_quote`.
