/api/v1/mystery/feed/recent read:catalog Recent pack openings, across all partners by default. Page with ?limit (1–100) and ?offset; add ?scope=mine to see only your own, and ?game= to keep a single-game storefront from over-fetching the whole pool. Rows are unique on (token_id, revealed_at) — NOT token_id alone: a card sold back to the pool and pulled again appears once per reveal, so key any UI list on the pair.
GET /api/v1/mystery/feed/recent?limit=10 These inputs are shared across all docs pages, so an id entered here carries over.
{
"success": false,
"message": "Mystery partner API key required",
"error": "This endpoint requires an API key linked to a mystery partner account"
}curl -X GET 'https://service.rip.fun/api/v1/mystery/feed/recent?limit=10' \ -H 'X-API-Key: rip_…'
| Field | Type | Required | Description |
|---|---|---|---|
limit | query int | — | 1–100, default 50 |
offset | query int | — | 0–10000 |
scope | query string | — | `mine` → only this key’s pulls |
game | query string | — | Filter to one game (same ids as the catalog: pokemon, onepiece, …). Tiers with no game metadata are excluded when set |
fresh | query bool | — | `true` bypasses the shared response cache and recomputes from source. Meant for a manual refresh, not for polling: it carries its own budget of 10 calls per minute per key, and past that you get a 429 while a plain read still answers from cache |
data)| Field | Description |
|---|---|
items[].token_id / item_type | Revealed on-chain item. Unique per (token_id, revealed_at), not per token |
items[].card_name / card_image_url / card_price_usdc | Hydrated card metadata + value |
items[].tier_id | Tier the pull came from (integer — tier ids are numbers everywhere in this API) |
items[].game | { id, label } for the tier's game, null when the tier has no metadata |
items[].revealed_at | Reveal timestamp |