> ## 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.

# Orders

> Pulling what a seller has to fulfil, and recording that it shipped.

```
/v1/sellers/{sellerId}/orders
```

Read-only, with one exception: an order records something that already happened.

## Pull incrementally

```http theme={null}
GET /v1/sellers/42/orders?filter[updatedSince]=2026-09-23T08:00:00Z&include=items.watch,addresses
```

Without `updatedSince` you walk the whole history every time. With it, and cursor
paging, one call per run keeps you in step.

**include=items.watch** `string`

The sold listing beside the order — carrying the `externalIdentifier` you gave
it, which is how you recognise your own product.

**include=addresses** `string`

The name and address the buyer entered, which is what you need to ship. `kind`
says which is which: `SHIPPING` or `BILLING`. The buyer's account is not reachable:
an order gives you what the order needs.

Item names and prices are copies taken at the moment of sale, so a listing edited
or removed afterwards does not change what somebody bought.

## Finding an order, and counting them

`filter[q]` is the dashboard's order search, by the same rule: the order number (with
or without `#`), the buyer's name or email, the street, postcode or city of one of its
addresses, or the name, model or brand of the watch.

```http theme={null}
GET /v1/sellers/42/orders?filter[q]=202610100
```

Every page carries `meta.statusCounts`: how many orders the business has in each
status — the dashboard's seven tabs always, at `0` when empty, plus any other status
it has orders in — across all of its orders, whatever you filtered.

## What the order page shows

`paymentMethod` is how the buyer paid: `card`, `ideal`, `bancontact`, `eps`, `p24`,
`paypal`, or `customer_balance` for a bank transfer.

`buyerEmail` and `buyerPhone` are how to reach the buyer, as the dashboard shows them —
to our own app only, and only once the order has gone through: `null` while it is
`awaiting_payment` or `awaiting_manual_review`. A partner's system gets the addresses
shipping needs, not a person's contact details.

`receiptUrl` is the receipt as a PDF, at `/v1/sellers/{sellerId}/orders/{id}/receipt`:
the file the dashboard downloads, and the one the buyer has. It is `null` until the order is
paid: a receipt proves a purchase, and the address answers `404` for an unpaid order.

## Recording a shipment

The one thing about an order a seller decides. Only the number has to be sent:

```json theme={null}
{ "data": { "type": "orders", "id": "4471", "attributes": {
  "trackingNumber": "1Z999AA10123456784"
}}}
```

We recognise the courier from the number (`ups`, here) and build the link the buyer
follows from it. Spaces are taken out of the number and letters made capitals, as it
is stored.

**courier** `string`

Leave it out and we recognise it from the number. A number that fits several couriers
goes to the one with the lowest `detectionPriority`; one that fits none we know, or
only couriers without a priority, is recognised as none: then you are asked for it
with a `422` on `courier`. One you send is used, whatever the number looks like.

**trackingUrl** `string`

The link the buyer's shipping email and order page send them to. Leave it out for a
courier we build the link for (`buildsTrackingUrl` in `GET /v1/couriers`); some, like
PostNL, need the postcode, which we take from the order's shipping address. For
`other`, a courier we have no link for, or an address without the postcode the link
needs, it is required: a `422` on `trackingUrl`. One you send is kept as it is.

This is not three fields being filled in: the order moves to `in_transit` and the
buyer is told, exactly as from the dashboard. It needs `orders:write`, so a token
that only pulls orders cannot reach it.

Only an order that is paid and not sent yet can be shipped: `payment_received`, or one
you are bringing to us in person that has no tracking yet.

## Correcting the tracking

A wrong number can be put right while the parcel is on its way, with the same `PATCH`:

* `in_transit`: the buyer gets an email with the new link — but only when the
  courier, number or link actually changed. Sending the same details again tells
  nobody anything.
* `awaiting_delivery` with tracking: it is stored, and the buyer is not told, as when
  it was recorded.

A shipment is described whole each time. What you leave out is worked out again from
the number, not kept from before: a corrected number sent alone does not keep the
courier and link of the parcel it replaces.

Once the order is delivered, completed, cancelled, refunded or returned, the tracking
is the record of how it went. Anything other than the statuses above answers `409`
with `order_not_shippable`, and `meta.status` names the status it is in.

## The carriers we know

`courier` must be one of these, so a name we do not know is refused with `422`.
`GET /v1/couriers` answers the same list with the names the dashboard shows, and per
courier what the dashboard uses to fill in the rest:

**trackingNumberPatterns** `string[]`

How its numbers look: regular expressions using only anchors, classes and counts, so
they read the same on every platform. Match them against the number without spaces and
in capitals, and preselect the courier when exactly one matches. When several match,
take the one with the lowest `detectionPriority` — what we do on the server.

**detectionPriority** `number | null`

1 to 5 for the couriers most shops ship with — DHL Express, FedEx, UPS, DHL, PostNL —
and null for the rest. A number several patterns fit (twelve digits are FedEx and GLS
alike) goes to the lowest; if none of them has one, recognise none.

**buildsTrackingUrl** `boolean`

Whether we build the link, so `trackingUrl` may be left out.

**trackingUrlTemplate** `string | null`

The link we build, to show as a preview: `{number}`, and where the carrier needs them
`{country}` (ISO 3166 alpha-2) and `{postcode}` (without spaces) from the order's
shipping address. Leave the link out when you can; we make it.

| | | | |
| - | - | - | - |
| `bpost` | `bring` | `brt` | `budbee` |
| `chronopost` | `collis-prive` | `collisimo` | `correos` |
| `correos-express` | `ctt-express` | `cycloon` | `delivengo` |
| `deutsche-post` | `dhl` | `dhl-express` | `dpd` |
| `dpd-local` | `evri` | `fedex` | `fedex-crossborder` |
| `gls` | `hermes` | `homerr` | `inpost` |
| `lettre-suivie` | `mondial-relay` | `mrw` | `nacex` |
| `osterreichische-post` | `parcel-france` | `postnl` | `quicargo` |
| `royal-mail` | `sda-express` | `spring` | `storeshippgers` |
| `suer` | `tnt-italy` | `trunkrs` | `ups` |
| `viatim` | `yodel` | | |

And **`other`**, for a carrier we do not have yet. The order still moves and the
buyer is still told.

> [!TIP]
>
> Read this list from `GET /v1/couriers` rather than copying it into your code: it
> is the same list the server validates against, and we add carriers.

The exception is an order the seller is bringing to us in person
(`awaiting_delivery`), where recording a courier does not move it and does not tell
the buyer a second time.

Every other attribute of an order is the record of what happened, and the body never
changes one: anything but `courier`, `trackingNumber` and `trackingUrl` — `status`,
`total`, `payoutAmount`, `buyerEmail`, `createdAt` and the rest — is refused with
`403 read_only_field`, one error per field.


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