Prepare redemption

POST /api/v1/mystery/redemption/prepare cards:redeem

Starts a physical redemption: validates + stores the address, snapshots the cheapest shipping rate, pre-creates the fulfillment order/queue rows, and — once KYC (Veriff) is clear — returns unsigned initiateBurn calldata in the same {chain_id, calls} shape as purchase/prepare. The END USER signs the burn from the wallet holding the NFT. Idempotent per idempotency_key / per (purchase, token) while pre-burn.

Try it POST /api/v1/mystery/redemption/prepare money

These inputs are shared across all docs pages — an id entered here carries over.

request body
object · 3 keys
{
  "purchase_id": 0,
  "shipping_address": {
    "name": "Demo Buyer",
    "street1": "1 Market St",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94105",
    "country": "US"
  },
  "idempotency_key": "demo-redeem-0-single"
}
response

Not run yet — press Run to make a live call against https://staging-service.rip.fun (through this demo's server-side proxy; the API key never reaches the browser).

curl (tracks the inputs above)
curl -X POST 'https://staging-service.rip.fun/api/v1/mystery/redemption/prepare' \
  -H 'X-API-Key: rip_v1_…' \
  -H 'Content-Type: application/json' \
  -d '{"purchase_id":0,"shipping_address":{"name":"Demo Buyer","street1":"1 Market St","city":"San Francisco","state":"CA","zip":"94105","country":"US"},"idempotency_key":"demo-redeem-0-single"}'

Request fields

FieldTypeRequiredDescription
purchase_idnumberyesThe fulfilled purchase holding the item
token_idstringRequired when the purchase revealed multiple items
idempotency_keystringReplay-safe; an Idempotency-Key header is also accepted
shipping_address.namestringyesRecipient full name
shipping_address.street1stringyesStreet line 1 (`street2` optional)
shipping_address.citystringyesCity
shipping_address.statestringState / region
shipping_address.zipstringyesPostal code
shipping_address.countrystringyesISO country code, e.g. `US` (`phone`, `email` optional)

Response fields (data)

FieldDescription
redemption_id / statusAWAITING_KYC (no calldata yet) or PREPARED
kyc.status / kyc.kyc_urlNOT_REQUIRED | PENDING | APPROVED | DECLINED; send the user to kyc_url while PENDING
shipping_quoteSnapshotted cheapest rate (same shape as /quote)
expires_atPREPARED calldata validity (default 24 h); EXPIRED is retryable with a NEW idempotency_key
unsigned.chain_id / unsigned.calls[]initiateBurn calldata for the user to sign — null until KYC clears

Errors

StatusCodeWhen
409not_fulfilledpurchase not revealed yet
409not_burnabletoken unindexed / burned / not in a redeemable state, or already queued
409not_ownertoken left the purchase wallet — the holder must be the burn signer
409redemption_existsre-preparing after the burn already started
400invalid_addressShippo cannot validate the address
409kyc_required(on submit) burn submitted while still AWAITING_KYC

See Errors for the response envelope and the full code list.

Flow

  1. Partner: POST /redemption/quote at checkout to show shipping cost (optional, no rows)
  2. Partner: POST /redemption/prepare with the address (+ idempotency_key)
  3. If AWAITING_KYC: send the end user to kyc.kyc_url (Veriff); re-call prepare after approval (same key) to get calldata
  4. End user: signs + broadcasts unsigned.calls (initiateBurn) from the wallet holding the NFT
  5. Partner: POST /redemption/submit with {redemption_id, tx_hash} → BURN_SUBMITTED
  6. rip.fun: warehouse ships the item; poll GET /redemption/:purchase_id or consume redemption.updated webhooks (IN_FULFILLMENT → COMPLETED; burn finalizes on dispatch)