Concepts

# Field filtering

Reduce response payload size by requesting only the fields you need, using the camelCase JSON field names you already see in responses. Every endpoint supports them: as query parameters on reads, and as request body fields on creates, line adds, label writes and drawing uploads.

## Include fields

Add `fields` to the query string with a comma-separated list:

```bash
GET /v1/orders:query?pageSize=50&fields=orderId,statusName,createdAt
```

```json
{
  "orders": [
    { "orderId": "order_abc", "statusName": "Draft",   "createdAt": "2026-08-01T00:00:00Z" },
    { "orderId": "order_def", "statusName": "Pending", "createdAt": "2026-08-02T00:00:00Z" }
  ],
  "nextPageToken": "eyJv..."
}
```

Envelope keys such as `nextPageToken` are always preserved — paths are relative to the resource, not the envelope.

## Exclude fields

Use `excludeFields` to drop specific fields and keep everything else:

```bash
GET /v1/quotes:query?pageSize=50&excludeFields=lines,notes
```

## Nested fields

Use dot notation to reach inside nested objects:

```bash
GET /v1/orders:query?fields=orderId,total.amountMicros
```

```json
{
  "orders": [
    { "orderId": "order_abc", "total": { "amountMicros": "50000000" } }
  ],
  "nextPageToken": "eyJv..."
}
```

## Paths across arrays

A path that crosses an array is applied to every element. `labels.name` keeps `name` on every label and drops the rest of each one:

```bash
GET /v1/orders:query?fields=orderId,labels.name
```

```json
{
  "orders": [
    {
      "orderId": "order_abc",
      "labels": [ { "name": "Rush" }, { "name": "Trade" } ]
    }
  ],
  "nextPageToken": "eyJv..."
}
```

## Detail endpoints

Filtering works identically on single-resource GETs. You do not need to name the wrapper key:

```bash
GET /v1/quotes/quote_abc?fields=quoteId,total.amountMicros
```

```json
{
  "quote": {
    "quoteId": "quote_abc",
    "total": { "amountMicros": "22000000" }
  }
}
```

## Write operations

Creates, line adds, label writes and drawing uploads take the same two options, but as fields on the request body rather than in the query string. A `?fields=` query parameter on these endpoints is ignored:

```bash
POST /v1/orders

{
  "customerId": "cust_abc",
  "reference": "PO-4471",
  "lines": [ ... ],
  "fields": "orderId,statusName"
}
```

```json
{
  "order": {
    "orderId": "order_abc",
    "statusName": "Draft"
  }
}
```

## Rules

- Field names are **camelCase** — the same names you see in responses.

- Dot paths map across arrays. `labels.name` keeps `name` on every element of `labels`.

- If both `fields` and `excludeFields` are supplied, `fields` wins and the other is ignored. It is not an error.

- Naming a field that does not exist on the resource is a no-op — silently omitted, not rejected.

- Filtering applies to `2xx` JSON responses only. Error bodies are never filtered.

---

Source: https://developer.factory.app/filtering · Factory Sales API v1
