Prepare to accept an offer
POST/api/market/offers/{id}/accept/prepare
Step 1 of accepting, for the UTXO's current holder only: checks the offer is active and the UTXO unspent at the same address and value, and returns the offer transaction with input 0 (your UTXO) ready for your wallet. It carries no bidder signature.
Path parameters #
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | yes | The offer id (16 hex characters). |
Request body #
content-type: application/json
| Field | Type | Required | Description |
|---|---|---|---|
seller_address | string | yes | The address that holds the UTXO (the offer's seller_address). |
seller_public_key | string | yes | Its public key, hex (Taproot: the internal key, x-only or compressed; SegWit: compressed). |
Example request #
curl -X POST 'https://raresats.net/api/market/offers/dbf866a1e7e209e7/accept/prepare' \
-H 'content-type: application/json' \
-d '{
"seller_address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
"seller_public_key": "03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115"
}'const response = await fetch('https://raresats.net/api/market/offers/dbf866a1e7e209e7/accept/prepare', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({
"seller_address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
"seller_public_key": "03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115"
})
});
const data = await response.json();import requests
data = requests.post("https://raresats.net/api/market/offers/dbf866a1e7e209e7/accept/prepare", json={
"seller_address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr",
"seller_public_key": "03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115"
}).json()Response 200 #
| Field | Type | Description |
|---|---|---|
psbt | string | The offer transaction, base64, with input 0 ready for your wallet. It carries no bidder signature (the server adds them). |
sign | array of object | Input 0, your UTXO: sign it with your wallet's default sighash. |
sign[].index | integer | The input to sign. |
sign[].address | string | The address whose key signs it. |
sign[].sighash | integer | The 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). |
summary | object | The trade you accept. |
summary.outpoint | string | Your UTXO. |
summary.value | integer | Its value in sats (it goes to the bidder). |
summary.price | integer | What you receive, in sats (output 1, to your address). |
summary.platform_fee | integer | The bidder's platform fee. |
summary.network_fee | integer | The network fee, paid by the bidder. |
summary.total | integer | What the bidder pays. |
summary.vsize | integer | Estimated virtual size. |
summary.fee_rate | number | sat/vB, fixed by the bidder. If it confirms slowly, you can speed it up by spending output 1 (CPFP). |
summary.unit_price | number | (price - value) / count. |
summary.row | string | The UTXO's own row. |
summary.count | integer | Sats of row in the UTXO. |
summary.bidder_ordinals_address | string | Where the UTXO goes. |
summary.listing_id | string | null | Your live listing of the UTXO, if any: accepting sells it (sold once confirmed). |
{
"psbt": "cHNidP8BAP0fAQIAAAACfxBUfmD8FgvLWC+rhhI7HaW1ncmmlqpbSg8h3N/usyQAAAAAAP3///9Bihr4H2G1iZuygx3BHzwLSWfyqpoJAv/W0tpPJYLJAQAAAAAA/f///wUQJwAAAAAAACJRIKgvKZRNZbhq5rXlzHXilOrWxZORoe3F4BbjSYxn/Hu7sK0BAAAAAAAiUSCmCGnw288dxlnJzsuvgFATXqnozcSHBT8dxogJSdxoTL4KAAAAAAAAIlEgrfKcXTOb9Ymo27aSDRsOplytPApoV4riNE46JGW7F/AvJxUAAAAAACJRIKgvKZRNZbhq5rXlzHXilOrWxZORoe3F4BbjSYxn/Hu7AAAAAAAAAAAOagxyYXJlc2F0cy5uZXQAAAAAAAEBKxAnAAAAAAAAIlEgpghp8NvPHcZZyc7Lr4BQE16p6M3EhwU/HcaICUncaEwBFyDMikvGTYl73cX7wvZw96i6CzhneRBs8SI8b8XXzW/BFQABAStg4xYAAAAAACJRIKgvKZRNZbhq5rXlzHXilOrWxZORoe3F4BbjSYxn/Hu7AAAAAAAA",
"sign": [
{
"index": 0,
"address": "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr"
}
],
"summary": {
"outpoint": "24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0",
"value": 10000,
"price": 110000,
"platform_fee": 2750,
"network_fee": 963,
"total": 113713,
"vsize": 321,
"fee_rate": 3,
"unit_price": 100000,
"row": "decasat_alpha",
"count": 1,
"bidder_ordinals_address": "bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh",
"listing_id": "5e1cb930f43354c3"
}
}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_json | The body is not valid JSON. |
| 400 | bad_public_key | A public key is not hex, or not a valid secp256k1 key of the right size. |
| 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). |
| 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 | changed | The UTXO's value is not what the PSBT says, or (wallet tools) a UTXO, its sats or the transaction being replaced changed since prepare: prepare again. |
| 409 | config_changed | The marketplace settings changed since this purchase or transfer was prepared (prepare it again), or since this offer was made (it is now invalid, reason config_changed). |
| 409 | expired | The prepared purchase, offer or transfer expired, or the offer itself has: prepare it again. |
| 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 | spent | The UTXO (or a listing's UTXO) is spent or does not exist. |
| 413 | too_large | The body is over 256 KiB. |
| 415 | not_json | A POST without content-type: application/json. |
| 422 | key_mismatch | The public key does not control the address. |
| 422 | legacy_address | A legacy (P2PKH, 1…) address: use Taproot or SegWit. |
| 422 | not_owner | The UTXO does not belong to the seller address, or (wallet tools) to the owner's addresses, or the transfer was made by another wallet. |
| 422 | pubkey_mismatch | The trade engine found the public key is not the address's key. |
| 422 | unsupported_address | An address type the marketplace does not trade (only Taproot, native SegWit and nested SegWit). |
| 422 | unsupported_script | The trade engine met a script type it does not support. |
| 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. |
| 500 | internal | A server bug. Report it. |
| 503 | bitcoind_unavailable | bitcoind is not available. |
| 503 | engine_unavailable | The trade engine is not available. |
| 503 | fork_unavailable | The rare-sat index is not available. |
| 503 | market_unavailable | The marketplace is closed right now (its backends disagree on the network, or are unreachable). |
| 503 | oracle_unavailable | The ord oracle is not available. |
{
"error": "24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0 is not held by bc1p4qhjn9zdvkux4e44uhx8tc55attvtyu358kutcqkudyccelu0was9fqzwh: only its holder can accept",
"code": "not_owner",
"outpoint": "24b3eedfdc210f4a5baa96a6c99db5a51d3b1286ab2f58cb0b16fc607e54107f:0"
}Then sign input 0 with your wallet's default sighash and accept. You receive price at the address that holds the UTXO (output 1); the bidder pays the platform fee and the network fee.