# Listings and search

> Listings on sale, searched and filtered, and their photos.

Listings on sale, searched and filtered, and their photos. Generated from the [OpenAPI spec](https://dev.mongrl.com/openapi.json). Each endpoint says which key it needs; see [Authentication](https://dev.mongrl.com/guides/authentication.md).

| Method | Path | What it does |
|---|---|---|
| GET | [`/v1/images/{id}/{file}`](#get-a-photo) | Get a photo |
| GET | [`/v1/listings`](#search-listings-on-sale) | Search listings on sale |
| GET | [`/v1/listings/{id}`](#get-a-listing-on-sale) | Get a listing on sale |

## Get a photo

`GET /v1/images/{id}/{file}` · operation `getImage`

Public, for <img> tags: no key needed. `file` is thumb.jpg, medium.jpg or large.jpg. Never changes, so it's cached for a year.

**Auth:** None.

**Parameters**

| Name | In | Type | Notes |
|---|---|---|---|
| `id` * | path | string |  |
| `file` * | path | string | one of `thumb.jpg`, `medium.jpg`, `large.jpg` |

**Responses:** `200` OK · `default` [a problem](https://dev.mongrl.com/reference/conventions.md#errors)

## Search listings on sale

`GET /v1/listings` · operation `listListings`

Every parameter is optional. `q` matches the title, catalogue terms (brand, designer…) and description, ignoring accents and matching word beginnings ("henn" finds Henningsen). Filters combine: `term` matches any of the terms given per kind (brand A or B, and designer C), `attr` matches any of the values given per attribute. Prices are compared across currencies at the day's rate.

**Auth:** a secret or publishable key (`Authorization: Bearer sk_…` or `pk_…`)

**Parameters**

| Name | In | Type | Notes |
|---|---|---|---|
| `limit` | query | integer | ≥ 1; ≤ 100; default `24` |
| `cursor` | query | string | next_cursor from the previous page |
| `q` | query | string | Words to look for. max 200 chars |
| `sort` | query | string | relevance (default with q), newest (default without), popular (most saved). one of `relevance`, `newest`, `price_asc`, `price_desc`, `popular` |
| `category` | query | string | This category and its subcategories |
| `term` | query | string[] | Catalogue term ids, e.g. brands; repeat for several |
| `seller` | query | string |  |
| `attr` | query | string[] | key:value, e.g. condition:excellent; repeat for several |
| `min_price` | query | integer | In minor units of currency. ≥ 0 |
| `max_price` | query | integer | In minor units of currency. ≥ 0 |
| `currency` | query | string | Show prices in this currency too (display_price); one of the marketplace's |

**Responses:** `200` [SearchOutputBody](#searchoutputbody) · `default` [a problem](https://dev.mongrl.com/reference/conventions.md#errors)

## Get a listing on sale

`GET /v1/listings/{id}` · operation `getListing`

Listings not on sale are 404 here; sellers see theirs under /v1/me/listings.

**Auth:** a secret or publishable key (`Authorization: Bearer sk_…` or `pk_…`)

**Parameters**

| Name | In | Type | Notes |
|---|---|---|---|
| `id` * | path | string |  |
| `currency` | query | string | Show prices in this currency too (display_price); one of the marketplace's |

**Responses:** `200` [ListingBody](#listingbody) · `default` [a problem](https://dev.mongrl.com/reference/conventions.md#errors)

## Schemas

Fields marked * are always present in responses and required in requests.

### SearchOutputBody

| Field | Type | Notes |
|---|---|---|
| `items` * | [ListingBody](#listingbody)[] |  |
| `next_cursor` | string |  |
| `total` * | integer | How many listings match |

### ListingBody

| Field | Type | Notes |
|---|---|---|
| `attributes` * | map of any | The marketplace's own fields |
| `category_id` | string |  |
| `closed_at` | string (date-time) |  |
| `commission_percent` | number (double) | Console only: overrides the marketplace's commission; absent means the default |
| `created_at` * | string (date-time) |  |
| `custody` * | string | Where it is: at the seller's, being collected, or stored. one of `seller`, `collecting`, `stored` |
| `delivery` * | [Delivery](#delivery) | How the item can reach the buyer |
| `description` * | string |  |
| `display_price` | [MoneyBody](#moneybody) | The price in the requested currency, converted at the day's rate (approximate; the final amount is set at checkout) |
| `favorite_count` * | integer | How many users have saved it |
| `favorited` | boolean | Whether the signed-in user has saved it (only with X-User-Session) |
| `fulfilment` * | string | Who moves it to the buyer. one of `seller`, `marketplace` |
| `id` * | string |  |
| `images` * | [ImageBody](#imagebody)[] | In display order; the first is the main photo |
| `locale` * | string | The language the seller wrote in |
| `location` * | [LocationBody](#locationbody) |  |
| `offer` | [MoneyBody](#moneybody) | The price the marketplace offers (valuation_offered) |
| `offer_note` | string | A note with the offer |
| `offer_schedule` | [PriceStepBody](#pricestepbody)[] | The price drops offered with the price (valuation_offered) |
| `price` | [MoneyBody](#moneybody) | Base price, in the seller's currency |
| `price_schedule` | [PriceStepBody](#pricestepbody)[] | The price falls in these steps while on sale |
| `published_at` | string (date-time) |  |
| `review_note` | string | Why the marketplace denied it (denied) |
| `seller_blocked` | boolean | The seller is blocked, so the listing is out of the shop |
| `seller_id` * | string |  |
| `shipping_size` | string | Prices delivery from the marketplace's shipping table |
| `site` | [SiteRefBody](#siterefbody) | The marketplace location it's stored at or being collected to |
| `status` * | string | one of `draft`, `pending_valuation`, `valuation_offered`, `pending_approval`, `published`, `closed`, `denied` |
| `stock` * | integer |  |
| `stored_at` | string (date-time) | Stored since |
| `terms` * | map of [TermRefBody](#termrefbody) | By kind, e.g. brand |
| `title` * | string |  |
| `updated_at` * | string (date-time) |  |
| `wants_storage` | boolean | The seller asked to have it collected and stored |

### Delivery

| Field | Type | Notes |
|---|---|---|
| `buyer_arranged` | boolean |  |
| `pickup` | boolean |  |
| `shipping` | [Shipping](#shipping) |  |

### MoneyBody

| Field | Type | Notes |
|---|---|---|
| `amount` * | integer | In minor units: 125000 SEK is 1 250,00 kr. ≥ 0 |
| `currency` * | string | ISO 4217, one of the marketplace's |

### ImageBody

| Field | Type | Notes |
|---|---|---|
| `height` | integer |  |
| `id` * | string |  |
| `status` * | string | Sizes exist once ready. one of `processing`, `ready`, `failed` |
| `urls` | map of string | thumb (400 px square), medium (800 px), large (1600 px); cacheable forever |
| `width` | integer |  |

### LocationBody

| Field | Type | Notes |
|---|---|---|
| `city` | string |  |
| `country` | string | ISO 3166-1 alpha-2, e.g. SE |
| `postal_code` | string |  |

### PriceStepBody

| Field | Type | Notes |
|---|---|---|
| `amount` * | integer | The new price, in minor units. ≥ 1 |
| `done` | boolean | It has applied |
| `months` * | integer | Months after the schedule starts (the listing goes on sale, or the schedule changes while on sale). ≥ 1; ≤ 60 |
| `on` | string (date-time) | When it applies (once on sale) |

### SiteRefBody

| Field | Type | Notes |
|---|---|---|
| `buyer_pickup` | boolean | Buyers may collect purchases here |
| `city` | string |  |
| `id` * | string |  |
| `kind` * | string | one of `showroom`, `warehouse` |
| `name` * | string |  |

### TermRefBody

| Field | Type | Notes |
|---|---|---|
| `descriptions` | map of string | About the brand, designer…, by locale (e.g. en, sv); on single listings only |
| `id` * | string |  |
| `name` * | string |  |
| `slug` * | string |  |

### Shipping

| Field | Type | Notes |
|---|---|---|
| `additional_item_price` | integer | ≥ 0 |
| `price` | integer | For the first item; omit for "ask for a quote". ≥ 0 |
