> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shipstream.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Selecting Fields

The ShipStream Global API adheres to REST API principles, but provides advanced features for selecting which
fields to return in the response, similar in a way to GraphQL APIs.

## Optional Fields

To provide the fastest possible response times while not limiting the scope of the API,
some endpoints do not return all documented fields unless they are requested using an additional
query parameter called `fields` or one prefixed with `fields:`. These "optional" fields are
denoted in the field descriptions in the API reference with the text `Optional Field`.

**Example requesting optional fields `qty_locked` and `is_pickable`:**

```http Request theme={null}
GET /api/global/v1/inventory/locations?fields=qty_locked,is_pickable
```

To request that *all* optional fields be returned, a shortcut keyword `all` may be used. However, it
is recommended to request only the fields you need, to reduce processing time and conserve bandwidth.

**Example requesting all location fields (including all optional fields):**

```http Request theme={null}
GET /api/global/v1/inventory/locations?fields=all
```

<Note>
  Note that when a property which references another model is added using `fields`, either
  explicitly or implied with `all`, only the "reference" to that object (an object with `type`
  and `id`) is added to the response. However, the referenced objects including all or some of their
  properties can also be added to the response to avoid additional round-trips to fetch them.
  Please read the "Including Referenced Objects" section below for more info.
</Note>

<Info>
  The `all` keyword will not automatically include all fields of referenced objects as well. I.e. its behavior
  is not recursive.
</Info>

## Including Referenced Objects

For your convenience, and to potentially save a large number of round-trips, you can have the API return
object data for objects that are referenced by `type` and `id` in the same response. This object data
for additionally included objects is added to the `included` property of the response by requesting one
or more fields of the referenced objects. The `included` property is an object of lists with a key for each
included object `type` which contains a list of included objects of that type.

The corresponding query parameter for including referenced objects will be the path of the reference to the
object from the top-level object as if it was included inline and prefixed with `fields:`.

**Example requesting a collection of locations as well as the `sku` and `name` of every location's `product`:**

```http Request theme={null}
GET /api/global/v1/inventory/locations?fields:product=sku,name
```

The response in this example would look like this:

```json Response theme={null}
{
  "collection": [
    {
      "type": "Location",
      "id": 442,
      "...": "...",
      "product": {
        "type": "Product",
        "id": 33
      }
    }
  ],
  "included": {
    "Product": [
      {
        "type": "Product",
        "id": 33,
        "sku": "ABC",
        "name": "ABC Widget"
      }
    ]
  }
}
```

<Info>
  If the same object is referenced multiple times by different fields or items, it will still only be included once
  so no data is duplicated.
</Info>

### Basic and Optional Fields

For your convenience, since some fields are fairly ubiquitous, you may use the `basic` keyword
as a value of the parameter to imply that all non-optional fields shall be returned.

**Example requesting all basic (non-optional) fields of the referenced `Product` object:**

```http Request theme={null}
GET /api/global/v1/inventory/locations?fields:product=basic
```

As with the top-level objects, referenced objects may also contain fields denoted as `Optional Field`
in the descriptions and these will not be returned when requesting `basic`, but may be listed
individually or implied using `all` to return all basic *and* optional fields.

**Example requesting a mix of basic and optional fields of the referenced `Product` object:**

```http Request theme={null}
GET /api/global/v1/inventory/locations?fields:product=basic,weight,dimensions
```

**Example requesting all fields of the referenced `Product` object:**

```http Request theme={null}
GET /api/global/v1/inventory/locations?fields:product=all
```

### Deeply-Referenced Fields

The `all` keyword only implies that the *first* level of fields shall be returned and deeply-referenced fields are
not implied but **can** be included in many cases as well. For example, since a `Location` references a `Product` using
a property called `product` and the `Product` references a `Merchant` using a property called `merchant`, you can
request that the `Merchant` data be included in the response using `fields:product.merchant`.

**Example requesting all top-level fields as well as all fields of a referenced object and a deeply-referenced object:**

```http Request theme={null}
GET /api/global/v1/inventory/locations?fields=all&fields:product=all&fields:product.merchant=all 
```

You will need to de-reference the field data client-side by searching the `included` object for the matching
`type` and then searching the list of objects for the matching `id`.

For example, the response for the above query may have this shape (irrelevant fields replaced with "..." for simplicity):

```json Response theme={null}
{
  "collection": [
    {
      "type": "Location",
      "id": 442,
      "...": "...",
      "product": {
        "type": "Product",
        "id": 33
      }
    },
    {
      "type": "Location",
      "id": 444,
      "...": "...",
      "product": {
        "type": "Product",
        "id": 33
      }
    }
  ],
  "included": {
    "Product": [
      {
        "type": "Product",
        "id": 33,
        "...": "...",
        "merchant": {
          "type": "Merchant",
          "id": 2
        }
      }
    ],
    "Merchant": [
      {
        "type": "Merchant",
        "id": 2,
        "name": "ACME, Inc.",
        "code": "acme",
        "...": "..."
      }
    ]
  }
}
```
