# Selling

> The sell form, drafts, photos, publishing, valuations, storage and the seller's listings.

Any signed-in user can sell. A listing starts as a draft, gets photos, and is published: straight on sale, to the marketplace's team for approval, or to be valued first. All calls send the user's session.

## What the marketplace asks for

Read `GET /v1/marketplace` → `listings` before building the form:

| Field | Meaning |
|---|---|
| `min_images` | Photos needed to go on sale (at least 1 to be valued). |
| `require_category` | A category is needed. |
| `required_terms` | Term kinds needed, e.g. `["brand"]`. |
| `attributes_schema` | A JSON Schema for the marketplace's own fields (condition, dimensions…). Render a field per property and send the values in `attributes`. |
| `valuations` | Sellers may ask the team to value the listing instead of setting a price. |
| `require_approval` | The team reviews listings before they go on sale. |

## Statuses

```text
draft ──publish──▶ published                       (no approval needed)
draft ──publish──▶ pending_approval ──▶ published   (the team approves)
                                     └─▶ denied     (with review_note)
draft ──publish {ask_valuation}──▶ pending_valuation ──▶ valuation_offered
valuation_offered ──accept──▶ pending_approval
valuation_offered ──counter──▶ pending_approval     (the team approves, denies or offers again)
published ──close──▶ closed ──publish──▶ …
```

`GET /v1/me/listings` returns the seller's listings in every status, latest change first, with cursor paging.

## 1. Start a draft

```http
POST /v1/me/listings
{ "title": "Lounge chair", "locale": "sv" }
```

A draft can be incomplete. Save as the seller goes: `PUT /v1/me/listings/{id}` **replaces** the listing's content, so always send the whole form, not just the changed field.

| Field | Notes |
|---|---|
| `title`, `description` | Plain text. `locale` is the language the seller writes in. |
| `price` | `{ "amount": 650000, "currency": "SEK" }`, minor units, one of the marketplace's currencies. Leave it out when asking for a valuation. |
| `category_id`, `terms` | `terms` maps a kind to a term id: `{ "brand": "…", "designer": "…" }`. |
| `attributes` | The marketplace's own fields, matching `attributes_schema`. |
| `location` | `{ "country": "SE", "postal_code": "…", "city": "…" }`. A country is needed to publish. |
| `delivery` | How it can reach the buyer: `shipping` (with a `price`, or none for "ask for a quote"), `pickup`, `buyer_arranged`. At least one. See [Shipping and delivery](https://dev.mongrl.com/guides/delivery.md). |
| `stock` | 1 unless the seller has several of the same. |

## 2. Add photos

Send each photo as the request body, with its content type:

```http
POST /v1/me/listings/{id}/images
Content-Type: image/jpeg

<the file's bytes>
```

- JPEG, PNG or WebP, up to 20 MB and 50 megapixels, at most 20 per listing.
- The answer is `202` with the image in `processing`. Its sizes are ready within seconds; poll `GET /v1/me/listings/{id}` until `status` is `ready`.
- `PUT /v1/me/listings/{id}/images/order` with every image id sets the order; the first is the main photo.
- `DELETE /v1/me/listings/{id}/images/{image_id}` removes one.

Upload from your server: the browser sends the file to your server, which streams it on with the user's session.

## 3. Publish

```http
POST /v1/me/listings/{id}/publish
{ "ask_valuation": false, "wants_storage": false }
```

- With approval on, only the basics are checked (title, photos, country, price), because the team completes the listing.
- `ask_valuation: true` (where `valuations` is on): no price needed; the listing goes to `pending_valuation`.
- `wants_storage: true`: the seller asks the marketplace to collect the listing and store it until it sells. The team books the collection; until then it stays with the seller.
- If anything is missing, the `422` lists **every** problem in `errors`, so you can mark all the fields at once.

A closed listing can be published again the same way.

## Valuations

When the team has valued it, the listing is `valuation_offered` with:

- `offer`: the price offered, and `offer_note`, why.
- `offer_schedule`: price drops offered with it, if any.

The seller answers:

- `POST /v1/me/listings/{id}/offer/accept`: the offer becomes the price.
- `POST /v1/me/listings/{id}/offer/counter` with `{ "amount": 720000 }`: their own price, in the offer's currency.

Either way the listing goes to `pending_approval`. A denied listing has `review_note` with the reason; show it, and don't offer to send it again.

## On sale

- `price_schedule` lists the drops ahead: each step has `months`, `amount`, `on` (when it applies) and `done`. Show the seller what's coming.
- `custody` says where it is (`seller`, `collecting`, `stored`), and `site` which showroom or warehouse. `fulfilment` says who delivers it (`seller` or `marketplace`).
- Editing a listing on sale keeps it on sale, so it must stay complete. Sellers can't edit a listing while the team reviews it, and closed or denied listings can't be edited.
- `POST /v1/me/listings/{id}/close` takes it off sale. `DELETE` removes a draft; a listing that was ever on sale is closed instead.

## When it sells

The seller sees the order under `GET /v1/me/orders?as=seller`. If the seller delivers it themselves, they mark it sent with tracking details. See [Checkout and orders](https://dev.mongrl.com/guides/checkout.md#moving-an-order-on). They're paid once the buyer has it, after setting up [payouts](https://dev.mongrl.com/guides/payouts.md).

## Emails mongrl sends sellers

When the team offers a price, denies a listing or puts it on sale, the seller gets an email linking to `https://<your shop>/<lang>/account/listings/<id>`. Build that page. See [Pages your shop needs](https://dev.mongrl.com/guides/storefront-pages.md).
