raresats.net API
Listings API View as Markdown

Get listings by outpoint

Look up whether UTXOs are listed, one or up to 100 at a time. Both forms return only live listings: active, or pending while a purchase is in the mempool. A sold, cancelled or moved listing is no longer the outpoint's.

One outpoint #

GET/api/market/listings/by-outpoint/{outpoint}

The live listing (active, or pending while a purchase is in the mempool) of one outpoint, or 404 not_listed.

Path parameters #

ParameterTypeRequiredDescription
outpointstringyesThe UTXO, txid:vout.

Example request #

cURL
curl 'https://raresats.net/api/market/listings/by-outpoint/8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0'
JavaScript
const response = await fetch('https://raresats.net/api/market/listings/by-outpoint/8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0');
const data = await response.json();
Python
import requests

data = requests.get("https://raresats.net/api/market/listings/by-outpoint/8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0").json()

Response 200 #

FieldTypeDescription
idstringThe listing id: 16 lowercase hex characters.
outpointstringThe listed UTXO, txid:vout.
valueintegerThe UTXO's own value in sats (it moves to the buyer whole).
priceintegerThe listing price in sats: exactly what the seller receives. The buyer pays this plus the platform fee and the network fee.
unit_pricenumberPrice per sat of the listing's own row: (price - value) / count, to the hundredth of a sat. Floors and the unit sort use it.
rowstringThe 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.
countintegerHow many sats of row the UTXO holds (the "×N" of a bulk listing).
rowsmap of integerEvery row the UTXO's tracked sats count toward, with their counts (label rows included).
typesarray of TypeGroup | nullThe UTXO's sats grouped by exact type combination, rarest first.
satsinteger | nullTracked sats in the UTXO (all rows).
rangesarray of array of integer | nullThe tracked sats as inclusive [first, last] ranges, ascending.
yearsmap of integer | nullTracked sats per mint year (UTC year of the block that mined them).
seller_addressstringThe address that holds the UTXO and signed the listing.
payout_addressstringWhere the price is paid (the seller's payment output).
statusstringactive (for sale), pending (a purchase is in the mempool), sold, cancelled (or replaced by a newer listing of the same UTXO), moved (spent elsewhere). A listing whose UTXO was sold through an accepted offer ends sold with sold_via: "offer".
created_atintegerUnix seconds.
updated_atintegerUnix seconds of the last status change.
txidstring | nullThe purchase transaction, while pending and once sold; otherwise null.
signature_publicbooleantrue 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.
sold_viastring | nulloffer 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.
offer_idstring | nullThe accepted offer it was sold through (sold_via: "offer"), else null.
best_offerBestOffer | nullThe best active offer on the UTXO, or null.
spent_by_pendingobjectA transaction still in the mempool that spends an output (spent_by_pending). Absent when nothing pending spends it.
spent_by_pending.txidstringThe spending transaction.
spent_by_pending.vininteger | nullIts input that spends the output.
spent_by_pending.first_seeninteger | nullWhen the transaction was first seen in the mempool (bitcoind's entry time), unix seconds.
spent_by_pending.fee_ratenumber | nullIts fee rate, sat/vB (one decimal).
spent_by_pending.salebooleanWhether the spend sells this output (a pending sale with it as the seller's input).
spent_by_pending.replaceablebooleanAlways true (full RBF): the spend may still be replaced.
in_bundlebooleanOnly 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_countinteger | nullWith in_bundle: how many sats of the row asked for it holds.
Response
{
  "id": "3324d08569806818",
  "outpoint": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0",
  "value": 6280,
  "price": 94200,
  "unit_price": 14,
  "row": "block9",
  "count": 6280,
  "rows": {"block9": 6280, "block9_1st_tx": 6280},
  "types": [
    {
      "types": ["block9", "nakamoto", "vintage"],
      "count": 6280,
      "sats": [45100023043, 45100023044, 45100023045]
    }
  ],
  "sats": 6280,
  "ranges": [[45100023043, 45100029322]],
  "years": {"2009": 6280},
  "seller_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
  "payout_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
  "status": "active",
  "created_at": 1790952985,
  "updated_at": 1790952985,
  "txid": null,
  "signature_public": false,
  "sold_via": null,
  "offer_id": null,
  "best_offer": null
}

Errors #

{error, code}; see Errors for every code.

StatusCodeMeaning
400bad_outpointNot an outpoint (txid:vout).
400bad_pathThe path is not valid percent-encoding.
404not_listedThat outpoint has no live listing.
Error (400)
{"error": "not an outpoint (txid:vout)", "code": "bad_outpoint"}

Many outpoints #

GET/api/market/listings/by-outpoint

The batch form: the live listings of up to 100 outpoints at once, keyed by outpoint. Outpoints that are not listed are simply absent.

Query parameters #

ParameterTypeRequiredDescription
outpointsstringyes1-100 outpoints (txid:vout), comma-separated.

Example request #

cURL
curl 'https://raresats.net/api/market/listings/by-outpoint?outpoints=8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0,2fb6fb60ece3672924a373d7479d144d9ce4d3591185bfb5a00e62aedd53d3a9:0'
JavaScript
const response = await fetch('https://raresats.net/api/market/listings/by-outpoint?outpoints=8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0,2fb6fb60ece3672924a373d7479d144d9ce4d3591185bfb5a00e62aedd53d3a9:0');
const data = await response.json();
Python
import requests

data = requests.get("https://raresats.net/api/market/listings/by-outpoint", params={"outpoints": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0,2fb6fb60ece3672924a373d7479d144d9ce4d3591185bfb5a00e62aedd53d3a9:0"}).json()

Response 200 #

FieldTypeDescription
listingsmap of ListingThe live (active or pending) listing of each outpoint asked for, keyed by outpoint. Outpoints with none are absent.
as_ofobject | nullWhen the marketplace last checked every live listing against the chain: the block height and unix seconds. null until the first check.
as_of.heightinteger | nullBlock height
as_of.checked_atintegerUnix seconds
Response
{
  "listings": {
    "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0": {
      "id": "3324d08569806818",
      "outpoint": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0",
      "value": 6280,
      "price": 94200,
      "unit_price": 14,
      "row": "block9",
      "count": 6280,
      "rows": {"block9": 6280, "block9_1st_tx": 6280},
      "types": [
        {
          "types": ["block9", "nakamoto", "vintage"],
          "count": 6280,
          "sats": [45100023043, 45100023044, 45100023045]
        }
      ],
      "sats": 6280,
      "ranges": [[45100023043, 45100029322]],
      "years": {"2009": 6280},
      "seller_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
      "payout_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
      "status": "active",
      "created_at": 1790952985,
      "updated_at": 1790952985,
      "txid": null,
      "signature_public": false,
      "sold_via": null,
      "offer_id": null,
      "best_offer": null
    }
  },
  "as_of": {"height": 969001, "checked_at": 1790952985}
}

Errors #

{error, code}; see Errors for every code.

StatusCodeMeaning
400bad_outpointNot an outpoint (txid:vout).
400bad_outpointsoutpoints lists none, or more than 100.
Error (400)
{"error": "outpoints must list 1-100 outpoints", "code": "bad_outpoints"}

An outpoint with no live listing is simply absent from listings; one malformed outpoint fails the whole request (400 bad_outpoint).