raresats.net API
Trading API View as Markdown

Prepare a listing

POST/api/market/listings/prepare

Step 1 of listing: checks each UTXO (confirmed, unspent, yours, tracked rare sats, no inscription or rune, a valid price) and returns the PSBT to sign with SIGHASH_SINGLE|ANYONECANPAY. Nothing is stored yet.

Request body #

content-type: application/json

FieldTypeRequiredDescription
seller_addressstringyesThe address holding the UTXOs: Taproot (bc1p…), native SegWit (bc1q…) or nested SegWit (3…, P2SH-P2WPKH). Legacy 1… is refused.
seller_public_keystringyesThe public key of seller_address, hex: for Taproot the internal (untweaked) key, 32-byte x-only or 33-byte compressed; for SegWit the 33-byte compressed key.
payout_addressstringnoWhere the price is paid. Optional: defaults to seller_address. Any standard mainnet address.
itemsarray of objectyes1 to 50 UTXOs, each listed at its own price. One PSBT, one wallet prompt. (1-50 items)
items[].outpointstringyesThe UTXO to list, txid:vout.
items[].priceintegeryesIts price in sats: what you receive. Above the UTXO's own value, at least 546 and at least the payout output's dust limit.

Example request #

cURL
curl -X POST 'https://raresats.net/api/market/listings/prepare' \
  -H 'content-type: application/json' \
  -d '{
  "seller_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
  "seller_public_key": "0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145",
  "payout_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
  "items": [
    {
      "outpoint": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0",
      "price": 94200
    }
  ]
}'
JavaScript
const response = await fetch('https://raresats.net/api/market/listings/prepare', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    "seller_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
    "seller_public_key": "0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145",
    "payout_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
    "items": [
      {
        "outpoint": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0",
        "price": 94200
      }
    ]
  })
});
const data = await response.json();
Python
import requests

data = requests.post("https://raresats.net/api/market/listings/prepare", json={
    "seller_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
    "seller_public_key": "0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145",
    "payout_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
    "items": [{
        "outpoint": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0",
        "price": 94200
    }]
}).json()

Response 200 #

FieldTypeDescription
psbtstringThe unsigned listing PSBT, base64: input i is UTXO i (with witnessUtxo, sighashType 0x83, tapInternalKey or redeemScript), output i pays its price to the payout address; version 2, locktime 0, sequence 0xfffffffd.
signarray of objectThe inputs to sign: every input, with sighash: 131.
sign[].indexintegerThe input to sign.
sign[].addressstringThe address whose key signs it.
sign[].sighashintegerThe sighash type to sign with, when it is not the default: 131 (0x83, SIGHASH_SINGLE|ANYONECANPAY) for listings. Absent on purchase inputs: sign with the default (SIGHASH_DEFAULT for Taproot, SIGHASH_ALL for SegWit v0).
itemsarray of objectWhat each listed UTXO will show.
items[].outpointstringThe UTXO.
items[].valueintegerIts value in sats.
items[].priceintegerIts listing price in sats.
items[].unit_pricenumber(price - value) / count.
items[].rowstringIts own row.
items[].countintegerSats of that row it holds.
Response
{
  "psbt": "cHNidP8BAF4CAAAAAWroye3nyLiwpcNzDMmz2aV449rKtugMlDF04UqR1gmLAAAAAAD9////AfhvAQAAAAAAIlEgqC8plE1luGrmteXMdeKU6tbFk5Gh7cXgFuNJjGf8e7sAAAAAAAEBK4gYAAAAAAAAIlEgqC8plE1luGrmteXMdeKU6tbFk5Gh7cXgFuNJjGf8e7sBAwSDAAAAARcgg9/oWjFR0lFykNpGH+KBVZHvafKxiizmPwFpeosxMUUAAA==",
  "sign": [
    {
      "index": 0,
      "address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
      "sighash": 131
    }
  ],
  "items": [
    {
      "outpoint": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0",
      "value": 6280,
      "price": 94200,
      "unit_price": 14,
      "row": "block9",
      "count": 6280
    }
  ]
}

Errors #

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

StatusCodeMeaning
400bad_addressAn address is not a mainnet address (or not one at all).
400bad_itemsitems is not a list of 1-50 UTXOs (or the PSBT lists more), or an item's sats is not null or a list of sat numbers.
400bad_jsonThe body is not valid JSON.
400bad_outpointNot an outpoint (txid:vout).
400bad_priceA price is not a whole number of sats.
400bad_public_keyA public key is not hex, or not a valid secp256k1 key of the right size.
400bad_requestThe body is not a JSON object, or the engine refused a malformed request (e.g. a purchase submitted without its signed setup PSBT).
400duplicate_outpointThe same UTXO twice in one listing.
403cross_originA POST from a browser on another site (a foreign Origin, or sec-fetch-site: cross-site). Server-side clients send no Origin and are not affected.
405method_not_allowedWrong method for the route; the allow header lists the right ones.
409pendingThe UTXO's listing is being bought, or an offer of it accepted, right now.
409spentThe UTXO (or a listing's UTXO) is spent or does not exist.
409unconfirmedThe UTXO is not confirmed yet.
409unindexedThe ord indexer does not know the UTXO yet.
413too_largeThe body is over 256 KiB.
415not_jsonA POST without content-type: application/json.
422bad_payoutA listed input is paired with an output that pays no address, or the payout address is the marketplace's fee address.
422inscribedThe UTXO carries an inscription: only rare sats are listed; the wallet tools only send it whole.
422key_mismatchThe public key does not control the address.
422legacy_addressA legacy (P2PKH, 1…) address: use Taproot or SegWit.
422no_rowThe UTXO holds no sat of a market row.
422not_ownerThe UTXO does not belong to the seller address, or (wallet tools) to the owner's addresses, or the transfer was made by another wallet.
422price_too_highThe price is above 21,000,000 BTC.
422price_too_lowThe price is at most the UTXO's own value, below 546 sats, or below the payout output's dust limit.
422pubkey_mismatchThe trade engine found the public key is not the address's key.
422runesThe UTXO carries runes (the wallet tools only send it whole).
422too_many_itemsToo many UTXOs in a listing, or listings in a purchase (max_bulk); for a wallet transfer, too many rare sats (and the runs between them) to lay out in one UTXO: choose fewer.
422unsupported_addressAn address type the marketplace does not trade (only Taproot, native SegWit and nested SegWit).
422unsupported_scriptThe trade engine met a script type it does not support.
422untrackedThe UTXO holds no rare sat the index tracks (send it whole instead).
429rate_limitedOver 30 POSTs a minute from your IPv4 address or IPv6 /64 (in chat, counted per IPv4 address or IPv6 /64: 30 writes and 20 login nonces a minute, 20 sign-ins and 10 display-name changes an hour; one message every 3 s and 20 a minute per address); wait retry-after seconds. With the AI moderation on, at most 6 messages and names a minute are checked per address and per IPv4 address or IPv6 /48.
503bitcoind_unavailablebitcoind is not available.
503engine_unavailableThe trade engine is not available.
503fork_behindThe rare-sat index has not caught up with bitcoind: try again in a minute.
503fork_unavailableThe rare-sat index is not available.
503indexer_behindThe ord indexer is catching up: try again shortly.
503market_unavailableThe marketplace is closed right now (its backends disagree on the network, or are unreachable).
503oracle_unavailableThe ord oracle is not available.
Error (422)
{
  "error": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0 carries an inscription: only rare sats are listed here",
  "code": "inscribed",
  "outpoint": "8b09d6914ae17431940ce8b6cadae378a5d9b3c90c73c3a5b0b8c8e7edc9e86a:0"
}

Sign every input listed in sign with sighash 0x83 (SIGHASH_SINGLE|ANYONECANPAY), then submit the listing. The whole flow, with code: List a UTXO.

  • Nothing is stored at this step; preparing twice is harmless.
  • For SegWit v0 sellers, small previous transactions are included as nonWitnessUtxo (some hardware wallets want them).