List active listings
GET/api/market/listings
Active listings, one page at a time, filtered by row and seller and sorted by unit price, price or age. Read-only, no rate limit beyond the edge's.
Query parameters #
| Parameter | Type | Required | Description |
|---|---|---|---|
row | string | no | Only listings of this row (collection), e.g. uncommon, block9, black_rare. A label row (e.g. block9_1st_tx) lists every listing lying in it. |
sub | string | no | With row: 1 also lists the row's rarer sub-categories (listings whose sats the row holds whole, e.g. alpha uncommons under uncommon). 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. |
sort | string | no | unit (unit price), price (listing price) or new (creation time). One of: unit, price, new. Default: unit. |
order | string | no | asc or desc. Default: asc, except desc for sort=new. Ties: newest first, then by id. One of: asc, desc. |
limit | integer | no | Page size, 1-200. Default: 50. (min 1, max 200) |
offset | integer | no | Listings to skip, 0-1,000,000. Default: 0. (min 0, max 1000000) |
seller | string | no | Only listings by this seller address. |
Example request #
curl 'https://raresats.net/api/market/listings?row=black_rare&sort=unit&order=asc&limit=2'const response = await fetch('https://raresats.net/api/market/listings?row=black_rare&sort=unit&order=asc&limit=2');
const data = await response.json();import requests
data = requests.get("https://raresats.net/api/market/listings", params={"row": "black_rare", "sort": "unit", "order": "asc", "limit": 2}).json()Response 200 #
| Field | Type | Description |
|---|---|---|
listings | array of Listing | One page of active listings, in the requested order. |
total | integer | Active listings matching the filters (all pages). |
as_of | object | null | When every live listing was last checked against the chain ({height, checked_at}), or null. |
as_of.height | integer | null | Block height |
as_of.checked_at | integer | Unix seconds |
contains | array of Listing | Only with row and contains=1: the first limit active listings holding some sats of the row among others (in bundle, each in_bundle: true), by total price, the cheapest first. Never in listings, total or the row's floor. |
contains_total | integer | Only with contains=1: how many such listings there are (all pages; contains=only pages them). |
{
"listings": [
{
"id": "1031931af1592e1c",
"outpoint": "2fb6fb60ece3672924a373d7479d144d9ce4d3591185bfb5a00e62aedd53d3a9:0",
"value": 546,
"price": 60546,
"unit_price": 60000,
"row": "black_rare",
"count": 1,
"rows": {"black_rare": 1},
"types": [
{
"types": ["black_rare", "omega"],
"count": 1,
"sats": [1657319999999999]
}
],
"sats": 1,
"ranges": [[1657319999999999, 1657319999999999]],
"years": {"2017": 1},
"seller_address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu",
"payout_address": "bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu",
"status": "active",
"created_at": 1790952985,
"updated_at": 1790952985,
"txid": null,
"signature_public": false,
"sold_via": null,
"offer_id": null,
"best_offer": null
}
],
"total": 1,
"as_of": {"height": 969001, "checked_at": 1790952985}
}Errors #
{error, code}; see Errors for every code.
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_address | An address is not a mainnet address (or not one at all). |
| 400 | bad_contains | contains is not 0, 1 or only, or is set without row. |
| 400 | bad_order | order is not asc or desc. |
| 400 | bad_paging | limit or offset out of range. |
| 400 | bad_row | row is not a row id. |
| 400 | bad_sort | sort is not unit, price or new. |
| 400 | bad_sub | sub is not 0 or 1. |
| 404 | retired_row | row is a row the site retired (uncommon_2009, rare_2009): its listings are its parent row's. retired names the row and the parent and years to ask for. |
{"error": "sort must be unit, price or new", "code": "bad_sort"}Sorting and paging #
sort=unit(the default) orders byunit_price, the price per sat of the listing's own row: the way to find a collection's cheapest sats.sort=priceorders by the listing price,sort=newby creation time.orderdefaults toasc, exceptdescforsort=new(newest first). Equal values come newest first, then by id, so pages are stable.- Page with
limit(1-200) andoffset;totalcounts every match. Listings can sell or move between two pages; re-read the first page when it matters.
Filters #
rowfilters by a listing's own row. Withsub=1it also lists the row's rarer sub-categories (listings whose sats the row holds whole). A label row such asblock9_1st_txlists every listing lying in it.contains=1(withrow) adds, apart, the listings that hold only some sats of the row among others (in bundle: a 330-sat Block 9 chunk holding one Block 9 palindrome, underblock9_palindrome) ascontains, the firstlimitby total price, withcontains_total. Each is markedin_bundle: truewithcontains_count, its sats of the row. They are priced as the whole UTXO: theirunit_priceis their own row's, so they are never inlistings,totalor the row's floor.contains=onlyanswers them alone aslistingsandtotal, paged bylimitandoffset.sellerlists one seller's active listings (the site's "My listings").- Only
activelistings are listed. Apending, sold, cancelled or moved listing is still readable by id (Get a listing).
To filter listings by mint year, mint day, birthday (month-day) or one rarer sub-category, use Query listings; see Filtering & birthday sats.