# Shipping and delivery

> How a listing reaches the buyer, how delivery is priced from the marketplace's shipping table, and letting buyers book a delivery time.

A listing reaches the buyer in one of a few ways, and who moves it depends on the listing. mongrl prices it; your checkout offers the choices and shows the quote.

## Who moves it

Every listing has `fulfilment`:

- **`seller`**: the seller ships it or hands it over. The ways they offer are in the listing's `delivery`.
- **`marketplace`**: the marketplace's team delivers it, typically because it's stored at their showroom or warehouse (`custody: stored`, `site`).

## The delivery methods

| `delivery.method` | Offered when | Price |
|---|---|---|
| `shipping` | Seller listings with `delivery.shipping`, and every marketplace listing. | The seller's `shipping.price`, or the marketplace's shipping table (below). No price means "we'll send a quote". |
| `pickup` | Seller listings with `delivery.pickup`: the buyer picks it up from the seller. | Free |
| `buyer_arranged` | Seller listings with `delivery.buyer_arranged`: the buyer sends their own courier. | Free |
| `collect` | Marketplace listings stored at a site where `site.buyer_pickup` is true: the buyer collects it there. | Free |

When a listing offers only one method you can leave `method` out. Offer the choices from the listing, then quote with the buyer's pick.

## The shipping table

Listings the marketplace moves are priced from its table, in `GET /v1/marketplace` → `shipping`:

- **`sizes`**: size classes, e.g. small parcel, armchair, sofa. Each listing has a `shipping_size`.
- **`zones`**: where buyers are, by `countries` and optional `postal_prefixes`. Each zone has a `delivery_time` to show buyers, e.g. "2–5 working days".
- **`options`**: delivery services, e.g. standard and white glove, with an `about` text. Send the buyer's pick as `delivery.option` (the first when left out).
- **`delivery`**: prices by option, size and zone. A missing price means a quote.
- **`collection`**: what it costs to collect a listing that's still at the seller's, by size and the seller's zone. mongrl adds it to the shipping line by itself.

You don't need to work prices out: send the address and option in the [quote](https://dev.mongrl.com/guides/checkout.md#1-quote) and show what comes back. Use the table only for hints such as "delivery from €49" or the delivery time.

The address needs at least `country` (and `postal_code` where zones use prefixes) to be priced. Without it the quote says `shipping_address_needed`.

## Booking a delivery time

Some marketplaces let buyers choose when the delivery comes (`shipping.booking`: weekdays, time windows, how far ahead). It applies to paid orders that the marketplace ships to a zone it books.

```http
GET /v1/me/orders/{id}/delivery-booking
```

```json
{
  "booked": null,
  "changeable": true,
  "slots": [
    { "date": "2026-10-23", "window": "am", "label": "08–12", "full": false },
    { "date": "2026-10-23", "window": "pm", "label": "13–17", "full": true }
  ]
}
```

- `409` means this order has no time to book (not paid yet, collected, or the carrier arranges it). Show nothing.
- Show `slots` grouped by `date`; `full` ones can't be chosen.
- Book with `PUT /v1/me/orders/{id}/delivery-booking` and `{ "date": "2026-10-23", "window": "am" }`.
- `changeable` turns false once it's too close to change. The booked time is in `booked`.

## Storage fees (sellers)

When a seller asks the marketplace to store their listing (`wants_storage` when publishing), storage can cost a monthly fee by size after `free_storage_weeks`. It's taken from the seller's payout when it sells and shown on the order as `payout.storage_fee`. Show sellers `shipping.storage_fees` and the free weeks before they choose storage.
