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

# A seller's own settings

> What a business calls itself, its company details, whether it takes offers, and its registrations.

```
PATCH /v1/sellers/{id}
```

Scope `business:write`, and only for a business you act for. This is the
dashboard's settings screen — the app is the dashboard on a phone, so it can do
what the dashboard does.

## What a business sees about itself

| Everybody | Only the business |
| - | - |
| `name`, `slug`, `city`, `country` | `email`, `invoiceEmail` |
| `acceptsPriceProposals`, `maximumDiscount` | `addressLine1`, `addressLine2`, `zipcode` |
| | `vat`, `kvk` (chamber of commerce number) |
| | `registrations`, `visible` |

The right-hand column comes back **`null`** to anybody else. A shop page is the
shop, not its tax details — and the shape of the resource stays the same either
way, so a client never has to handle a field that is sometimes missing.

## Company details

The same fields as the dashboard's settings form, by its rules:

* `name`, `email`, `addressLine1`, `zipcode`, `city` and `country` cannot be emptied:
  sending one as `null` is a `422` on it. A field you leave out is not asked about, so a
  business that never filled in its address can still be renamed.
* `email` may not be another business's.
* An `email` or `invoiceEmail` that looks mistyped — `gnail.com`, a domain that
  receives no mail — is a `422` with `implausible_email` and `meta.suggestion`. Send it
  again with `emailConfirmed` (or `invoiceEmailConfirmed`) set to the same address to
  keep it. The address already on file is never questioned.

```json theme={null}
{ "data": { "type": "sellers", "id": "42", "attributes": {
  "email": "shop@example.test",
  "invoiceEmail": "books@example.test",
  "kvk": "14026248",
  "vat": "NL001234567B01",
  "addressLine1": "Grote Staat 14", "zipcode": "6211 CW", "city": "Maastricht", "country": "NL"
}}}
```

## Offers

```json theme={null}
{ "data": { "type": "sellers", "id": "42", "attributes": {
  "acceptsPriceProposals": true,
  "maximumDiscount": 15
}}}
```

`maximumDiscount` is a percentage, and it is what `minimumProposal` on each
listing is worked out from: 15 on a €14,500 watch means no offer below €12,325 is
accepted. Nought is a business that will discuss but not discount; above 50 is
somebody who typed the price into the percentage box, so it is refused. A business we
set above 50 ourselves keeps its percentage: sending the stored value back is fine.

## Registrations

To sell into some countries a shop needs a registration for packaging, electronics or
batteries (EPR). `registrations` on the business is what the dashboard's compliance
settings list: one entry for **every** type there is, whether the shop has declared
anything for it or not, saying what it is (`name`, `description`, `placeholder`,
`country`, `supportsExpiry`), what may be declared for it (`declarations`, each a
`value` and a `label` to show), what the shop declared, and how far our check of the
number is (`status`: `pending`, `verified`, `invalid`, `expired`, with `statusMessage`
and `verifiedAt`). `declaration` is `null` for a type the shop has not answered yet.

Declaring is sending the types you change:

```json theme={null}
{ "data": { "type": "sellers", "id": "42", "attributes": {
  "registrations": [
    { "type": "de_lucid", "declaration": "number_provided", "number": "DE1234567890123", "expiresAt": "2027-06-30" },
    { "type": "de_weee_ear", "declaration": "not_applicable_mechanical" }
  ]
}}}
```

The types you leave out stay as they are. The rules are the settings page's, from the
same code: a number has to have the type's format and is stored in capitals without
spaces; a new or changed number is checked again (`pending` until it is confirmed — a
French number is looked up in the ADEME register straight away, and can come back
`verified` or `invalid`), and an unchanged one keeps its verification; any other declaration clears the number; a
declaration the type does not offer is refused. `number_provided` without a number
removes the registration, as emptying the field on the page does.

## Logo and cover

`logoHandle` and `coverHandle` take a handle from `POST /v1/uploads`
([Sending us a file](https://docs.wristler.eu/guides/uploads.md)) and replace the shop's logo or the wide image at
the top of its page; `null` removes it. They are write-only: `logo` (a URL) and the
`cover` relationship are what you read back.

## What is not yours to change

> [!WARNING]
>
> `slug` is the shop's address on the website. Changing it breaks every link
> anybody ever shared, so sending one is refused — leaving it out changes nothing.

A VAT number is checked when it changes, the same way the settings screen checks
it: its format, against the business's country (the one in the body, when you change
both). A number that is not really this business's turns every invoice we write into
the wrong invoice. A number that has been there for years is left alone, so changing
an address never fails over a field nobody touched.

## Listing a watch again

A shop that sells the same reference twice a month should not fill in the same
twelve fields twice a month. Any listing of the business can be copied, whatever its
status:

```json theme={null}
POST /v1/sellers/42/watches
{ "data": { "type": "watches", "attributes": {
  "duplicateOf": "91827",
  "price": 1395000
}}}
```

Everything the old listing says about the watch comes across — its
specifications, its gallery — and whatever the body carries is laid over the top.
The copy is a **draft**, and its `externalIdentifier` is cleared unless the body sends a
new one: two listings carrying the same one is exactly what that field exists to prevent.

It stays a draft until somebody publishes it. What it says about the watch is
right; what it says about *this* one — the photographs, the condition, the price —
is worth a look first.

This is the only way to sell a sold watch again: a sold listing itself cannot be put
back on sale, taken offline, turned into a draft or deleted (`409 listing_sold`). A
published copy goes through review like any new listing — and, like one, is refused with
`422` on `status` without a photo and a price (or `priceOnRequest`): its source's, or
the ones the body sends.

## Looking a reference up

```
GET /v1/references?filter[q]=126610
GET /v1/references/{id}
```

What the reference database knows about a watch, so a listing does not have to be
typed off the back of it. The detail answers in **our** vocabulary:
`specifications` keyed exactly as a listing's own, and `watchModel` as the id of
the model in our list.

```json theme={null}
{ "data": { "type": "references", "id": "0f9c…", "attributes": {
  "brand": "Rolex", "model": "Submariner", "reference": "126610LN",
  "specifications": { "CASE_MATERIAL": "STEEL", "MOVEMENT": "AUTOMATIC" },
  "watchModel": "482"
}}}
```

So the road is: look up, show what came back, let somebody correct it, and send it
as a listing.

Only values a listing may actually carry come back. The reference database knows
words we do not, and handing one over would make this a trap: you would send it
back and be told `422` on a field you never chose.

> [!NOTE]
>
> If the reference database is not answering, this is a `503` — never an empty
> list. "No such reference" is a different thing, and the wrong thing to tell
> somebody holding the watch.


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