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

# JSON:API in practice

> The conventions every endpoint here follows, and the three query parameters worth learning first.

Everything except the token endpoint speaks [JSON:API 1.0](https://jsonapi.org/) —
with two more exceptions: an upload of the file itself is sent as
`multipart/form-data`, and an invoice or receipt PDF comes back as
`application/pdf`. If you have used JSON:API before there are no surprises here; if
you have not, this page is the whole of what you need.

## Media type

```http theme={null}
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
```

A request that sends a body in another media type is refused with `415`, and one
that will not accept ours with `406`. Both are the specification's own rules, not
ours.

## The shape of a resource

```json theme={null}
{
  "data": {
    "type": "watches",
    "id": "91827",
    "attributes": { "reference": "126610LN", "price": 1450000 },
    "relationships": {
      "seller": {
        "data": { "type": "sellers", "id": "42" },
        "links": { "related": "https://api.wristler.eu/v1/sellers/42/watches/91827/seller" }
      }
    },
    "links": { "self": "https://api.wristler.eu/v1/sellers/42/watches/91827" }
  }
}
```

A collection answers with `data` as an array, and `links.next` when there is more.

A relationship's `data` is there when you `include` it. Its links are there only when we
serve that address: `related` where the related resource has a route of its own, `self`
(`…/relationships/{name}`) where the identifiers do — today only a listing's `images`, a
business's `statistics`, and the relations of an article and of the help centre. A
relationship with neither, and not included, is left out of `relationships` altogether.
Every link we hand out answers; to read a relation that has no link, `include` it.

## Three query parameters

**include** `string`

Related resources returned alongside, in `included`, comma separated:
`?include=images,watchModel`. An include we do not offer is refused with `400`
rather than ignored — a parameter silently dropped looks exactly like one that
worked.

**fields\[watches]** `string`

Only these attributes: `?fields[watches]=externalIdentifier,price,status`. Worth
using on a full inventory walk — a listing carries a long description and a
gallery, and a sync that only needs prices and stock wants neither.

**sort** `string`

A field name, prefixed with `-` for descending: `?sort=-updatedAt`. Each endpoint
in the reference names the fields it can sort on.

## Updating

A `PATCH` says only what it changes. Fields you leave out keep their current
values — the specification is explicit that a server must not read a missing
attribute as null, and we do not.

```json theme={null}
{ "data": { "type": "watches", "id": "91827", "attributes": { "price": 1395000 } } }
```

Sending a field that is ours to set on a listing or an order — a listing's
`reserved`, `purchasable` or `images`, an order's `total`, `status` or `createdAt` — is
refused with `403` and `read_only_field`, pointing at the field, rather than quietly
dropped, because a field ignored looks exactly like one that worked. That is every
attribute of either the reference marks read-only.

## Creating

Do not send `data.id`: we mint it, and a client-generated one is refused with
`403`. A successful create answers `201` with a `Location` header that matches
`data.links.self`.

Your own identifier for a listing goes in `externalIdentifier`, which is how you
find it again without keeping our ids. [More on that →](https://docs.wristler.eu/guides/inventory.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.