Skip to content

Prepare a collection offer

POST
/v1/policy-offers/preflight
curl --request POST \
--url https://api.digirare.com/v1/policy-offers/preflight \
--header 'Content-Type: application/json' \
--header 'x-session-token: <x-session-token>' \
--data '{ "bidder_public_key": "example", "delivery_address": "example", "alternatives": [ { "price_sats": 1, "expires_at": 1, "policy": { "scope": "asset", "asset": "example", "collection": "example", "max_supply_units": 1, "min_supply_units": 1, "issued_year": 1, "series": 1, "artist": "example" } } ], "funding": [ { "txid": "example", "vout": 1 } ], "exclude": [ { "txid": "example", "vout": 1 } ] }'

Selects (or verifies) the bidder’s confirmed, asset-free funding inputs, assigns a free confirmed market anchor, and builds 1..100 zero-fee v3 alternative parents sharing that funding set, returning the fund_policy_offer wallet request. Reserves nothing. 503 offer_capacity_full (retryable) when no anchor is free; 409 open_offer_limit at the per-address cap of open funding sets. Every policy-offer route answers 503 service_unavailable when collection-offer signing is unavailable.

Media typeapplication/json
object
bidder_public_key
required

P2TR: the 32-byte x-only internal key. P2WPKH: the 33-byte compressed key. Must own the session address.

string
/^[0-9a-f]+$/
delivery_address

Detach destination (any family); defaults to the session address.

string
alternatives
required
Array<object>
>= 1 items <= 100 items
object
price_sats
required
integer
>= 1 <= 9007199254740991
expires_at
required

Unix seconds in [now + 600, now + 90 days].

integer
policy
required

Funded_policy_offer_v1 canonical policy (spec 4.4). Exactly these keys, absent traits null; SHA256 of its canonical JSON is the leaf’s policy hash.

object
scope
required
string
Allowed values: asset collection
asset
required
One of:

Canonical compact Counterparty key. A subasset uses its A ID; asset_longname is display metadata.

string
collection
required
string | null
>= 1 characters <= 120 characters
max_supply_units
required
integer | null
min_supply_units
required
integer | null
issued_year
required
integer | null
series
required
integer | null
artist
required
string | null
>= 1 characters <= 200 characters
funding

Explicit funding inputs; otherwise confirmed asset-free coins are selected.

Array<object>
<= 8 items
object
txid
required
string
/^[0-9a-f]{64}$/
vout
required
integer
exclude
Array<object>
<= 200 items
object
txid
required
string
/^[0-9a-f]{64}$/
vout
required
integer

Unsigned zero-fee v3 alternative parents and the fund_policy_offer wallet request

Media typeapplication/json
object
result
required
object
protocol_version
required
Allowed value: funded_policy_offer_v1
operation_id
required
string
bidder
required

Mainnet P2TR or P2WPKH address. The SIGNING capability: every signature is verified by reconstructing a BIP-143/BIP-341 witness sighash.

string
internal_key
required
string
/^[0-9a-f]+$/
market_key
required
string
/^[0-9a-f]+$/
funding_slot_id
required
string
funding_inputs
required
Array<object>
>= 1 items <= 8 items
object
txid
string
/^[0-9a-f]{64}$/
vout
integer
value_sats
integer
>= 1 <= 9007199254740991
anchor
required
object
txid
string
/^[0-9a-f]{64}$/
vout
integer
value_sats
Allowed value: 330
delivery
required
object
mode
Allowed value: detached
address

Destination for a detached Counterparty balance. ANY address family Core accepts, legacy P2PKH included: a delivery address is a UTF-8 string inside the detach OP_RETURN, never a signer and never an output script. Deliberately wider than BitcoinAddress.

string
alternatives
required
Array<object>
>= 1 items <= 100 items
object
parent_txid
string
/^[0-9a-f]{64}$/
psbt_hex
string
/^[0-9a-f]+$/
leaf_hex
string
/^[0-9a-f]+$/
price_sats
integer
>= 1 <= 9007199254740991
offer_value_sats
integer
>= 1 <= 9007199254740991
expires_at
integer
policy

Funded_policy_offer_v1 canonical policy (spec 4.4). Exactly these keys, absent traits null; SHA256 of its canonical JSON is the leaf’s policy hash.

object
scope
required
string
Allowed values: asset collection
asset
required
One of:

Canonical compact Counterparty key. A subasset uses its A ID; asset_longname is display metadata.

string
collection
required
string | null
>= 1 characters <= 120 characters
max_supply_units
required
integer | null
min_supply_units
required
integer | null
issued_year
required
integer | null
series
required
integer | null
artist
required
string | null
>= 1 characters <= 200 characters
policy_hash
string
/^[0-9a-f]+$/
kind
string
parent_vsize
integer
parent_fee_sats
integer
change_sats
integer
detach_script_hex
string
/^[0-9a-f]+$/
signing
object
intent

Fund_policy_offer wallet intent claim (policy-offer-wallet.ts).

object
wallet_request
required

Xcp_signPsbts request: one PSBT per alternative, funding inputs only.

object
network_fee_sats
required
0
market_key_exposure_sats
integer
>= 1 <= 9007199254740991
reserves_funding
required
Example
{
"result": {
"protocol_version": "funded_policy_offer_v1",
"anchor": {
"value_sats": 330
},
"delivery": {
"mode": "detached"
},
"alternatives": [
{
"policy": {
"scope": "asset"
}
}
],
"network_fee_sats": 0,
"reserves_funding": false
}
}

Stable machine-readable failure

Media typeapplication/json
object
error
required
string
code
required
string
Allowed values: invalid_request unsupported_address_type unauthenticated forbidden not_found method_not_allowed state_changed expired invalid_transaction rate_limited internal_error upstream_unavailable service_unavailable checkout_changed target_unavailable signature_invalid template_mismatch mempool_rejected broadcast_unknown conflict_spend duplicate_funding_slot offer_selection_unavailable attached_delivery_single_item_only insufficient_funds insufficient_asset_balance price_below_minimum listing_price_above_maximum counter_price_invalid self_trade offer_capacity_full open_offer_limit policy_offer_refused
retryable
boolean
mempool_policy

On 422 mempool_rejected from a broadcast: which deterministic node policy refused the bytes. Retrying the same bytes fails the same way. fee_floor: re-quote at a higher fee_rate. chain_too_long: too many unconfirmed ancestors; wait for a confirmation, then retry. truc: a version-3 (TRUC) package rule, such as spending an unconfirmed version-3 output; wait for a confirmation, then retry.

string
Allowed values: fee_floor chain_too_long truc dust nonstandard
mempool_reason

The node’s own reject reason, on mempool_rejected (422) and on state_changed (409) when a broadcast lost to a conflicting or replacing spend.

string
wait_for_confirmation

Present and true when mempool_policy is chain_too_long or truc.

boolean
claims_released

On a checkout or accept completion refused as mempool_rejected: the journaled settlement ended and every listing, bid, and asset claim it held was released (its inputs were proven unspent). The quote or accept is replaced; request a new one.

boolean
refused_listings

Batch listing routes only: every refused item. The first sets the status and code.

Array<object>

One refused item in a batch refusal’s refused_listings array. Nothing in the batch was changed.

object
index
required
integer
listing_id
required
string
status
required
integer
code
required
string
error
required
string
key
additional properties
any
retry_after_seconds

On 429 rate_limited: the exact seconds until the oldest counted request leaves the window; a retry then is admitted (also sent as Retry-After). Limited writes are bucketed per route scope in exact sliding 60-second windows: by session address when a valid x-session-token is present, otherwise by IP, with a per-IP ceiling across sessions. Expensive writes: 20, ceiling 120. Signed completions: 120, ceiling 600. Session minting (/auth/*): 60 per IP. A request refused by any bucket is counted by none.

integer
>= 1
key
additional properties
any
Example
{
"code": "invalid_request",
"mempool_policy": "fee_floor"
}

Stable machine-readable failure

Media typeapplication/json
object
error
required
string
code
required
string
Allowed values: invalid_request unsupported_address_type unauthenticated forbidden not_found method_not_allowed state_changed expired invalid_transaction rate_limited internal_error upstream_unavailable service_unavailable checkout_changed target_unavailable signature_invalid template_mismatch mempool_rejected broadcast_unknown conflict_spend duplicate_funding_slot offer_selection_unavailable attached_delivery_single_item_only insufficient_funds insufficient_asset_balance price_below_minimum listing_price_above_maximum counter_price_invalid self_trade offer_capacity_full open_offer_limit policy_offer_refused
retryable
boolean
mempool_policy

On 422 mempool_rejected from a broadcast: which deterministic node policy refused the bytes. Retrying the same bytes fails the same way. fee_floor: re-quote at a higher fee_rate. chain_too_long: too many unconfirmed ancestors; wait for a confirmation, then retry. truc: a version-3 (TRUC) package rule, such as spending an unconfirmed version-3 output; wait for a confirmation, then retry.

string
Allowed values: fee_floor chain_too_long truc dust nonstandard
mempool_reason

The node’s own reject reason, on mempool_rejected (422) and on state_changed (409) when a broadcast lost to a conflicting or replacing spend.

string
wait_for_confirmation

Present and true when mempool_policy is chain_too_long or truc.

boolean
claims_released

On a checkout or accept completion refused as mempool_rejected: the journaled settlement ended and every listing, bid, and asset claim it held was released (its inputs were proven unspent). The quote or accept is replaced; request a new one.

boolean
refused_listings

Batch listing routes only: every refused item. The first sets the status and code.

Array<object>

One refused item in a batch refusal’s refused_listings array. Nothing in the batch was changed.

object
index
required
integer
listing_id
required
string
status
required
integer
code
required
string
error
required
string
key
additional properties
any
retry_after_seconds

On 429 rate_limited: the exact seconds until the oldest counted request leaves the window; a retry then is admitted (also sent as Retry-After). Limited writes are bucketed per route scope in exact sliding 60-second windows: by session address when a valid x-session-token is present, otherwise by IP, with a per-IP ceiling across sessions. Expensive writes: 20, ceiling 120. Signed completions: 120, ceiling 600. Session minting (/auth/*): 60 per IP. A request refused by any bucket is counted by none.

integer
>= 1
key
additional properties
any
Example
{
"code": "invalid_request",
"mempool_policy": "fee_floor"
}