Cancel listings
POST/api/market/listings/cancel
Takes active listings off sale with a BIP-322 signature by the seller address of raresats.net cancel <id,id,…> <unix seconds>. The stored signatures are deleted. A message is usable once and for 10 minutes.
Request body #
content-type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
ids | array of string | yes | 1 to 100 listing ids, all listed by address. (1-100 items) |
address | string | yes | The seller address that listed them. |
message | string | yes | Exactly raresats.net cancel <id,id,…> <unix seconds>: the ids comma-separated in the same order as ids, and the current time. At most 10 minutes old, at most 2 minutes ahead. |
signature | string | yes | A BIP-322 signature of message by address, base64 (what wallets' "sign message" with BIP-322 returns). |
Example request #
curl -X POST 'https://raresats.net/api/market/listings/cancel' \
-H 'content-type: application/json' \
-d '{
"ids": ["3324d08569806818"],
"address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
"message": "raresats.net cancel 3324d08569806818 1790949400",
"signature": "AUBGQvdc2H+7HTo1njZ1vlDxoX6ncoehAGbaHcAY1FtfSNg7lmo8Ih3WGInhAH/snOUIb8DkwRSQxc2dOu911Z9E"
}'const response = await fetch('https://raresats.net/api/market/listings/cancel', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
"ids": ["3324d08569806818"],
"address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
"message": "raresats.net cancel 3324d08569806818 1790949400",
"signature": "AUBGQvdc2H+7HTo1njZ1vlDxoX6ncoehAGbaHcAY1FtfSNg7lmo8Ih3WGInhAH/snOUIb8DkwRSQxc2dOu911Z9E"
})
});
const data = await response.json();import requests
data = requests.post("https://raresats.net/api/market/listings/cancel", json={
"ids": ["3324d08569806818"],
"address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
"message": "raresats.net cancel 3324d08569806818 1790949400",
"signature": "AUBGQvdc2H+7HTo1njZ1vlDxoX6ncoehAGbaHcAY1FtfSNg7lmo8Ih3WGInhAH/snOUIb8DkwRSQxc2dOu911Z9E"
}).json()Response 200 #
| Field | Type | Description |
|---|---|---|
listings | array of Listing | The cancelled listings (status: "cancelled"). |
warning | string | Present when some of them have a public signature (see exposed). |
exposed | array of string | Ids of cancelled listings whose signature a broadcast purchase made public: off sale here, but only moving the UTXO makes the cancel certain. |
{
"listings": [
{
"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": "cancelled",
"created_at": 1790952985,
"updated_at": 1790949401,
"txid": null,
"signature_public": false,
"sold_via": null,
"offer_id": null,
"best_offer": null
}
]
}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_ids | ids / listing_ids is empty, too long, malformed, or lists an id twice. |
| 400 | bad_json | The body is not valid JSON. |
| 400 | bad_message | The cancel message is not raresats.net cancel <ids> <unix seconds> or names other listings than ids; or the registration message is not raresats.net affiliate <address> <unix seconds> for address. |
| 400 | bad_request | The body is not a JSON object, or the engine refused a malformed request (e.g. a purchase submitted without its signed setup PSBT). |
| 400, 422 | bad_signature | 400: signature is missing or too long. 422: a signature does not verify (cancel or registration message, listing or purchase input). |
| 403 | cross_origin | A 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. |
| 404 | not_found | No such listing or offer. In chat: no such message. A display name to remove that does not exist. |
| 405 | method_not_allowed | Wrong method for the route; the allow header lists the right ones. |
| 409 | not_active | A listing (or offer) is not active: being bought (or accepted), sold, cancelled, moved, expired or invalid. Carries id and status. |
| 409 | replayed | That cancel or registration message was used already. |
| 413 | too_large | The body is over 256 KiB. |
| 415 | not_json | A POST without content-type: application/json. |
| 422 | future_message | The cancel or registration message is dated more than 2 minutes ahead: check the clock. |
| 422 | not_seller | A listing was not listed by address. |
| 422 | stale_message | The cancel or registration message is more than 10 minutes old: sign a new one. |
| 429 | rate_limited | Over 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. |
| 503 | engine_unavailable | The trade engine is not available. |
{
"error": "the cancel message is more than 10 minutes old: sign a new one",
"code": "stale_message"
}The message format, the time window, replays and what exposed means: Cancel listings guide.