Prepare redemption

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

Starts a physical redemption: stores the address, locks in the cheapest shipping rate, and returns the transaction the END USER sends from the wallet holding the card. That transaction flags the card for redemption — the card isn’t burned until the item ships, so nothing leaves the wallet yet. Only the holder can send it (rip.fun can’t do this one for them). Supply purchase_id OR token_id (token_id alone works for cards you distributed yourself). rip.fun runs no KYC/AML — screening your end user is your responsibility.

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 · 2 keys
{
  "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://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://service.rip.fun/api/v1/mystery/redemption/prepare' \
  -H 'X-API-Key: rip_…' \
  -H 'Content-Type: application/json' \
  -d '{"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_idnumberThe fulfilled purchase holding the item (supply this OR token_id)
token_idstringOn-chain token id (token-first; supply this OR purchase_id; also disambiguates a multi-item purchase)
item_typestring"CARD" | "GRADED_CARD" | "PACKET" | "SEALED_PRODUCT" — disambiguates a token number that exists as more than one asset (raw Card #N vs GradedCard slab #N)
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 / statusPREPARED — the transaction is ready to send
shipping_quoteSnapshotted cheapest rate (same shape as /quote)
expires_athow long the returned transaction stays valid (default 24 h); EXPIRED is retryable with a new idempotency_key
unsigned.chain_id / unsigned.calls[]the transaction the END USER sends from the wallet holding the card — flags it for redemption; the card burns when the item ships

Errors

StatusCodeWhen
400purchase_or_token_requiredneither purchase_id nor token_id supplied
409not_fulfilledpurchase path: purchase not revealed yet
409not_burnabletoken unindexed / burned / not in a redeemable state, or already queued
409not_ownertoken left the holder wallet — the holder must be the burn signer
404token_not_foundtoken-first: no rip.fun item for that token
409ambiguous_tokentoken-first: id is both a raw and a graded card — pass item_type ("CARD" or "GRADED_CARD") or use purchase_id
409item_type_mismatchitem_type contradicts what the token actually is
409redemption_existsre-preparing after the burn already started
400invalid_addressShippo cannot validate the address

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

Flow

  1. Partner: run any KYC/AML you need on the end user — rip.fun does not
  2. Partner: POST /redemption/quote at checkout to show shipping cost (optional)
  3. Partner: POST /redemption/prepare with purchase_id or token_id + the address → PREPARED + the transaction to send
  4. End user: sends that transaction from the wallet holding the card (pays gas) and gives you the tx hash — this flags the card; nothing moves yet
  5. Partner: POST /redemption/submit with { redemption_id, tx_hash } → BURN_SUBMITTED
  6. rip.fun: ships the item and burns the card when it ships; poll GET /redemption/:id or use redemption.updated webhooks