# Query listings

Active listings and marketplace activity, filtered by row, rarer sub-category, mint years, a mint day or a month-day, and sat luck: the marketplace counterpart of [Query sales](https://raresats.net/docs/get-sales-query.md). How the filters combine: [Filtering & birthday sats](https://raresats.net/docs/guide-filters.md).

Each listing of the query also names its lead sat with its block, mint day and luck (`lead`), and the block that created its UTXO (`utxo`): the columns of the site's listings grid.

## Listings

`GET /api/listings/query`

Active marketplace listings filtered like `/api/sales/query`, sorted like `/api/market/listings`, with facets. Not cached. 404 `{enabled: false}` while the marketplace is off.

#### Query parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `row` | string | no | Only this row (collection). None: every row. |
| `sub` | string | no | A rarer sub-category of `row` (e.g. `pizza_uncommon` under `uncommon`): only items holding sats of it. Implies `subs=1`. |
| `subs` | string | no | `1` includes the row's sub-category items (sold or listed under their own rows). One of: `0`, `1`. Default: `0`. |
| `contains` | string | no | With `row`: `1` also answers, apart, the listings holding only some sats of the row among others (in bundle: a Block 9 chunk holding one Block 9 palindrome under `block9_palindrome`) as `contains` (the first `limit`, in the asked `sort` and `order`; `sort=unit` orders them by total price, a bundle having no unit price of this row) and `contains_total`; `only` answers those alone as `listings`/`total`, paged by `limit` and `offset`. They are priced as the whole UTXO, never in the row's floor. One of: `0`, `1`, `only`. Default: `0`. |
| `years` | string | no | Mint years, comma-separated (`2009,2010`; up to 40): items holding a sat mined in one of them. Each must be a year sats were mined in, 2009 to this one (400 otherwise); repeats and order do not matter. `year` is accepted too. |
| `month` | string | no | A mint month, `YYYY-MM` (UTC, by each block's own time): items holding a sat mined that month. Combines with the other filters. |
| `blocks` | string | no | A block range: heights `from-to`, inclusive (`1000-5000`), or one block (`9`): items holding a sat mined in those blocks. Up to the tip (400 past it or for a malformed or reversed range). Combines with the other filters. |
| `date` | string | no | A mint day, `YYYY-MM-DD` (UTC), 2009 to this year: items holding a sat mined that day. Exclusive with `md`. |
| `md` | string | no | A month-day, `MM-DD`: items holding a sat mined that day of any year (with `years`, of those years). Birthday sats. |
| `luck` | string | no | Sat luck, a minimum (`8`: luck 8 or more) or an inclusive range (`8-12`), 0 to 254: items holding a sat of that luck. A sat's luck is its block's: the leading zero bits of the block hash less those of the block's target. Combines with the other filters (the matched sat passes them all). 503 for the few seconds after a first start while the luck of every block is read. |
| `sort` | string | no | `unit`, `price` or `new`. One of: `unit`, `price`, `new`. Default: `unit`. |
| `order` | string | no | `asc` or `desc`. Default: `asc`, except `desc` for `sort=new`. One of: `asc`, `desc`. |
| `limit` | integer | no | Page size, 1-200. Default: `50`. (min 1, max 200) |
| `offset` | integer | no | Listings to skip, 0-100,000. Default: `0`. (min 0, max 100000) |

#### Example request

```bash title="cURL"
curl 'https://raresats.net/api/listings/query?row=uncommon&years=2009&month=2017-12&blocks=1000-5000&luck=8'
```
```js title="JavaScript"
const response = await fetch('https://raresats.net/api/listings/query?row=uncommon&years=2009&month=2017-12&blocks=1000-5000&luck=8');
const data = await response.json();
```
```python title="Python"
import requests

data = requests.get("https://raresats.net/api/listings/query", params={"row": "uncommon", "years": "2009", "month": "2017-12", "blocks": "1000-5000", "luck": "8"}).json()
```

#### Response `200`

| Field | Type | Description |
| --- | --- | --- |
| `row` | string \| null | The row asked for. |
| `filter` | object | The filter as the server understood it. |
| `filter.years` | array of integer | The years asked for (ascending), `[]` for none. |
| `filter.month` | string \| null | The month asked for (`YYYY-MM`), `null` for none. |
| `filter.date` | string \| null | The day asked for. |
| `filter.md` | string \| null | The month-day asked for. |
| `filter.blocks` | object \| null | The blocks asked for: `{from, to}`, heights inclusive (one block: `from` = `to`), `null` for none. |
| `filter.blocks.from` | integer |  |
| `filter.blocks.to` | integer |  |
| `filter.luck` | object \| null | The luck asked for: `{min, max}` (`max` `null` for a minimum alone), `null` for none. |
| `filter.luck.min` | integer |  |
| `filter.luck.max` | integer \| null |  |
| `filter.sub` | string \| null | The sub-category asked for. |
| `filter.subs` | boolean | Whether sub-category items are included (absent on events and counts). |
| `filter.led` | boolean | Whether sales led by another row are included (`led=1`; sales only). |
| `total` | integer | Matching active listings. |
| `facets` | object \| null | Counts for refining the filter; `null` with `contains=only`. |
| `listings` | array of object | One page, in the requested order. |
| `listings[].id` | string | The listing id: 16 lowercase hex characters. |
| `listings[].outpoint` | string | The listed UTXO, `txid:vout`. |
| `listings[].value` | integer | The UTXO's own value in sats (it moves to the buyer whole). |
| `listings[].price` | integer | The listing price in sats: exactly what the seller receives. The buyer pays this plus the platform fee and the network fee. |
| `listings[].unit_price` | number | Price per sat of the listing's own row: `(price - value) / count`, to the hundredth of a sat. Floors and the `unit` sort use it. |
| `listings[].row` | string | The listing's own row (collection): the rarest market row holding every tracked sat of the UTXO, else the rarest market row present. Never a label row. |
| `listings[].count` | integer | How many sats of `row` the UTXO holds (the "×N" of a bulk listing). |
| `listings[].rows` | map of integer | Every row the UTXO's tracked sats count toward, with their counts (label rows included). |
| `listings[].types` | array of [TypeGroup](https://raresats.net/docs/listing-object.md) \| null | The UTXO's sats grouped by exact type combination, rarest first. |
| `listings[].sats` | integer \| null | Tracked sats in the UTXO (all rows). |
| `listings[].ranges` | array of array of integer \| null | The tracked sats as inclusive `[first, last]` ranges, ascending. |
| `listings[].years` | map of integer \| null | Tracked sats per mint year (UTC year of the block that mined them). |
| `listings[].seller_address` | string | The address that holds the UTXO and signed the listing. |
| `listings[].payout_address` | string | Where the price is paid (the seller's payment output). |
| `listings[].status` | string | `active` (for sale), `pending` (a purchase is in the mempool), `sold`, `cancelled` (or replaced by a newer listing of the same UTXO), `moved` (spent elsewhere). |
| `listings[].created_at` | integer | Unix seconds. |
| `listings[].updated_at` | integer | Unix seconds of the last status change. |
| `listings[].txid` | string \| null | The purchase transaction, while `pending` and once `sold`; otherwise `null`. |
| `listings[].signature_public` | boolean | `true` once a broadcast purchase put the seller's signature on the network: the listing can then be bought at this price anywhere until the UTXO moves, even after a cancel here. |
| `listings[].sold_via` | string \| null | `offer` when the listing ended `sold` through an accepted offer of its UTXO: `price` and `unit_price` are then the offer's (what was paid), `offer_id` names it. `null` otherwise. |
| `listings[].offer_id` | string \| null | The accepted offer it was sold through (`sold_via: "offer"`), else `null`. |
| `listings[].match` | object \| null | The sat that made the item pass a date or luck filter: its number, block, mint day (UTC) and luck. `null` without such a filter. |
| `listings[].match.sat` | integer | The sat. |
| `listings[].match.height` | integer | The block that mined it. |
| `listings[].match.date` | string \| null | Its mint day, YYYY-MM-DD. |
| `listings[].match.luck` | integer \| null | Its luck (its block's: the leading zero bits of the block hash less the target's); `null` while the luck table is being read. |
| `listings[].best_offer` | [BestOffer](https://raresats.net/docs/offer-object.md) \| null | The best active offer on the UTXO, or `null`. |
| `listings[].lead` | object \| null | The listing's lead sat: the sat that matched a date or luck filter, else the first sat of its rarest combination of types; its number, block, mint day (UTC) and luck (the grid's Luck column). `null` when the listing names no sat. |
| `listings[].lead.sat` | integer | The sat. |
| `listings[].lead.height` | integer | The block that mined it. |
| `listings[].lead.date` | string \| null | Its mint day, YYYY-MM-DD (UTC); `null` while the day table is being read. |
| `listings[].lead.luck` | integer \| null | Its luck (its block's: the leading zero bits of the block hash less the target's); `null` while the luck table is being read. |
| `listings[].utxo` | object \| null | The block that created the listed UTXO and that block's day (UTC), as the marketplace's last check of its listings saw it. `null` before the first check after the listing, or while the UTXO is unconfirmed. |
| `listings[].utxo.height` | integer | The block height. |
| `listings[].utxo.date` | string \| null | Its day, YYYY-MM-DD (UTC); `null` while the day table is being read. |
| `listings[].in_bundle` | boolean | Only on a listing read for a row it holds some sats of among others (in bundle: `contains=1`'s `contains`, or a row's activity): `true`. Its `price` is the whole UTXO's and its `unit_price` its own row's, never the row asked for. |
| `listings[].contains_count` | integer \| null | With `in_bundle`: how many sats of the row asked for it holds. |
| `as_of` | object \| null | When the marketplace last checked every live listing against the chain: the block height and unix seconds. `null` until the first check. |
| `as_of.height` | integer \| null | Block height |
| `as_of.checked_at` | integer | Unix seconds |
| `ms` | integer | Server time spent, ms. |
| `contains` | array of object | Only with `contains=1`: the first `limit` listings passing the filter that hold some sats of the row among others (in bundle, each `in_bundle: true`, its `lead` its first sat of the row), by total price, the cheapest first. Never in `listings`, `total` or `facets`. |
| `contains[].id` | string | The listing id: 16 lowercase hex characters. |
| `contains[].outpoint` | string | The listed UTXO, `txid:vout`. |
| `contains[].value` | integer | The UTXO's own value in sats (it moves to the buyer whole). |
| `contains[].price` | integer | The listing price in sats: exactly what the seller receives. The buyer pays this plus the platform fee and the network fee. |
| `contains[].unit_price` | number | Price per sat of the listing's own row: `(price - value) / count`, to the hundredth of a sat. Floors and the `unit` sort use it. |
| `contains[].row` | string | The listing's own row (collection): the rarest market row holding every tracked sat of the UTXO, else the rarest market row present. Never a label row. |
| `contains[].count` | integer | How many sats of `row` the UTXO holds (the "×N" of a bulk listing). |
| `contains[].rows` | map of integer | Every row the UTXO's tracked sats count toward, with their counts (label rows included). |
| `contains[].types` | array of [TypeGroup](https://raresats.net/docs/listing-object.md) \| null | The UTXO's sats grouped by exact type combination, rarest first. |
| `contains[].sats` | integer \| null | Tracked sats in the UTXO (all rows). |
| `contains[].ranges` | array of array of integer \| null | The tracked sats as inclusive `[first, last]` ranges, ascending. |
| `contains[].years` | map of integer \| null | Tracked sats per mint year (UTC year of the block that mined them). |
| `contains[].seller_address` | string | The address that holds the UTXO and signed the listing. |
| `contains[].payout_address` | string | Where the price is paid (the seller's payment output). |
| `contains[].status` | string | `active` (for sale), `pending` (a purchase is in the mempool), `sold`, `cancelled` (or replaced by a newer listing of the same UTXO), `moved` (spent elsewhere). |
| `contains[].created_at` | integer | Unix seconds. |
| `contains[].updated_at` | integer | Unix seconds of the last status change. |
| `contains[].txid` | string \| null | The purchase transaction, while `pending` and once `sold`; otherwise `null`. |
| `contains[].signature_public` | boolean | `true` once a broadcast purchase put the seller's signature on the network: the listing can then be bought at this price anywhere until the UTXO moves, even after a cancel here. |
| `contains[].sold_via` | string \| null | `offer` when the listing ended `sold` through an accepted offer of its UTXO: `price` and `unit_price` are then the offer's (what was paid), `offer_id` names it. `null` otherwise. |
| `contains[].offer_id` | string \| null | The accepted offer it was sold through (`sold_via: "offer"`), else `null`. |
| `contains[].match` | object \| null | The sat that made the item pass a date or luck filter: its number, block, mint day (UTC) and luck. `null` without such a filter. |
| `contains[].match.sat` | integer | The sat. |
| `contains[].match.height` | integer | The block that mined it. |
| `contains[].match.date` | string \| null | Its mint day, YYYY-MM-DD. |
| `contains[].match.luck` | integer \| null | Its luck (its block's: the leading zero bits of the block hash less the target's); `null` while the luck table is being read. |
| `contains[].best_offer` | [BestOffer](https://raresats.net/docs/offer-object.md) \| null | The best active offer on the UTXO, or `null`. |
| `contains[].lead` | object \| null | The listing's lead sat: the sat that matched a date or luck filter, else the first sat of its rarest combination of types; its number, block, mint day (UTC) and luck (the grid's Luck column). `null` when the listing names no sat. |
| `contains[].lead.sat` | integer | The sat. |
| `contains[].lead.height` | integer | The block that mined it. |
| `contains[].lead.date` | string \| null | Its mint day, YYYY-MM-DD (UTC); `null` while the day table is being read. |
| `contains[].lead.luck` | integer \| null | Its luck (its block's: the leading zero bits of the block hash less the target's); `null` while the luck table is being read. |
| `contains[].utxo` | object \| null | The block that created the listed UTXO and that block's day (UTC), as the marketplace's last check of its listings saw it. `null` before the first check after the listing, or while the UTXO is unconfirmed. |
| `contains[].utxo.height` | integer | The block height. |
| `contains[].utxo.date` | string \| null | Its day, YYYY-MM-DD (UTC); `null` while the day table is being read. |
| `contains[].in_bundle` | boolean | Only on a listing read for a row it holds some sats of among others (in bundle: `contains=1`'s `contains`, or a row's activity): `true`. Its `price` is the whole UTXO's and its `unit_price` its own row's, never the row asked for. |
| `contains[].contains_count` | integer \| null | With `in_bundle`: how many sats of the row asked for it holds. |
| `contains_total` | integer | Only with `contains=1`: how many such listings pass (all pages; `contains=only` pages them). |

#### Errors

`{error}` (a message, no code):

| Status | When |
| --- | --- |
| 400 | A malformed parameter (e.g. a `date` that is no date, `date` with `md`). |
| 404 | An unknown `row` or `sub`, or the marketplace is off (`enabled: false`). A retired row (`uncommon_2009`, `rare_2009`) answers 404 too, its `retired` field naming the row and years to ask for instead. |
| 503 | Mint dates or sat luck are still being read (`retry: true`): try again in a few seconds. Without `retry`: this server has no sat luck for its chain. |

## Activity

`GET /api/listings/events`

The marketplace's listed, cancelled and sold events of listings that pass the filter, newest first (the newest 2,000 events searched). Not cached. 404 while the marketplace is off.

#### Query parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `row` | string | no | Only this row (collection). None: every row. Events of every listing under the row, any kind (marked `sub` or `in_bundle` when its own row is another). |
| `sub` | string | no | A rarer sub-category of `row` (e.g. `pizza_uncommon` under `uncommon`): only items holding sats of it. Implies `subs=1`. |
| `years` | string | no | Mint years, comma-separated (`2009,2010`; up to 40): items holding a sat mined in one of them. Each must be a year sats were mined in, 2009 to this one (400 otherwise); repeats and order do not matter. `year` is accepted too. |
| `month` | string | no | A mint month, `YYYY-MM` (UTC, by each block's own time): items holding a sat mined that month. Combines with the other filters. |
| `blocks` | string | no | A block range: heights `from-to`, inclusive (`1000-5000`), or one block (`9`): items holding a sat mined in those blocks. Up to the tip (400 past it or for a malformed or reversed range). Combines with the other filters. |
| `date` | string | no | A mint day, `YYYY-MM-DD` (UTC), 2009 to this year: items holding a sat mined that day. Exclusive with `md`. |
| `md` | string | no | A month-day, `MM-DD`: items holding a sat mined that day of any year (with `years`, of those years). Birthday sats. |
| `luck` | string | no | Sat luck, a minimum (`8`: luck 8 or more) or an inclusive range (`8-12`), 0 to 254: items holding a sat of that luck. A sat's luck is its block's: the leading zero bits of the block hash less those of the block's target. Combines with the other filters (the matched sat passes them all). 503 for the few seconds after a first start while the luck of every block is read. |
| `limit` | integer | no | Events, 1-200. Default: `60`. (min 1, max 200) |

#### Example request

```bash title="cURL"
curl 'https://raresats.net/api/listings/events?row=uncommon&years=2009&month=2017-12&blocks=1000-5000&luck=8&limit=5'
```
```js title="JavaScript"
const response = await fetch('https://raresats.net/api/listings/events?row=uncommon&years=2009&month=2017-12&blocks=1000-5000&luck=8&limit=5');
const data = await response.json();
```
```python title="Python"
import requests

data = requests.get("https://raresats.net/api/listings/events", params={"row": "uncommon", "years": "2009", "month": "2017-12", "blocks": "1000-5000", "luck": "8", "limit": 5}).json()
```

#### Response `200`

| Field | Type | Description |
| --- | --- | --- |
| `row` | string \| null | The row asked for. |
| `filter` | object | The filter as the server understood it. |
| `filter.years` | array of integer | The years asked for (ascending), `[]` for none. |
| `filter.month` | string \| null | The month asked for (`YYYY-MM`), `null` for none. |
| `filter.date` | string \| null | The day asked for. |
| `filter.md` | string \| null | The month-day asked for. |
| `filter.blocks` | object \| null | The blocks asked for: `{from, to}`, heights inclusive (one block: `from` = `to`), `null` for none. |
| `filter.blocks.from` | integer |  |
| `filter.blocks.to` | integer |  |
| `filter.luck` | object \| null | The luck asked for: `{min, max}` (`max` `null` for a minimum alone), `null` for none. |
| `filter.luck.min` | integer |  |
| `filter.luck.max` | integer \| null |  |
| `filter.sub` | string \| null | The sub-category asked for. |
| `filter.subs` | boolean | Whether sub-category items are included (absent on events and counts). |
| `filter.led` | boolean | Whether sales led by another row are included (`led=1`; sales only). |
| `events` | array of object | Newest first. |
| `events[].seq` | integer | Event sequence number (rising). |
| `events[].type` | string | What happened. One of: `listed`, `cancelled`, `sold`. |
| `events[].listing_id` | string | The listing. |
| `events[].outpoint` | string | The listed UTXO. |
| `events[].row` | string | The listing's own row. |
| `events[].count` | integer | Sats of that row. |
| `events[].price` | integer | The listing price in sats. |
| `events[].unit_price` | number | The listing's unit price. |
| `events[].seller_address` | string | The seller (same as `seller`). |
| `events[].txid` | string \| null | The purchase transaction of a `sold` event; `null` otherwise. |
| `events[].time` | integer | Unix seconds. |
| `events[].seller` | string \| null | The seller's address. |
| `events[].buyer` | string \| null | A sale's buyer: the address the sats went to. `null` for other events, or when unknown. |
| `events[].affiliate` | string \| null | A sale bought here with an applied referral: the affiliate it paid. `null` otherwise. |
| `events[].sat` | integer | The sat that matched (absent without one). |
| `events[].match` | object \| null | The sat that made the item pass a date or luck filter: its number, block, mint day (UTC) and luck. `null` without such a filter. |
| `events[].match.sat` | integer | The sat. |
| `events[].match.height` | integer | The block that mined it. |
| `events[].match.date` | string \| null | Its mint day, YYYY-MM-DD. |
| `events[].match.luck` | integer \| null | Its luck (its block's: the leading zero bits of the block hash less the target's); `null` while the luck table is being read. |
| `events[].offer_id` | string \| null | The offer, on an offer event; `null` otherwise. |
| `events[].bidder` | string \| null | The bidder's payment address, on an offer event; `null` otherwise. |
| `events[].sub` | boolean | Only on an event read for a row (`row=`) that is not its own row but holds every tracked sat of the item (a sub-category or a label row): `true`. |
| `events[].in_bundle` | boolean | Only on an event read for a row (`row=`) whose listing or offer holds some sats of that row among others (in bundle, e.g. a Block 9 chunk under `block9_palindrome`): `true`. Its price and unit price are those of its own `row`. |
| `events[].contains_count` | integer \| null | With `in_bundle`: how many sats of the row asked for the item holds. |

#### Errors

`{error}` (a message, no code):

| Status | When |
| --- | --- |
| 400 | A malformed parameter (e.g. a `date` that is no date, `date` with `md`). |
| 404 | An unknown `row` or `sub`, or the marketplace is off (`enabled: false`). A retired row (`uncommon_2009`, `rare_2009`) answers 404 too, its `retired` field naming the row and years to ask for instead. |
| 503 | Mint dates or sat luck are still being read (`retry: true`): try again in a few seconds. Without `retry`: this server has no sat luck for its chain. |
