API guide
Every card on this site is available as JSON from
https://api.rifthunt.com. No key, no signup, no quota: all
requests are GET, all responses are
application/json, and CORS is open so you can call it straight
from a browser app.
Fair use
There is no hard rate limit, which is a request rather than a promise. Keep bursts under roughly 10 requests per second and put a short delay between calls in a loop.
If you want more than a few hundred cards, do not crawl: download the bulk export once and work locally. It is one request instead of a thousand and it is faster for you.
Send a User-Agent that identifies your project. If something
misbehaves, that is the difference between getting an email and getting
blocked.
Endpoints
| Request | Returns |
|---|---|
| GET /cards/search?q=… | Search. Same syntax as the site (see the syntax guide). Takes unique=, order= and dir=, below. |
| GET /cards/named?exact=… | One card by exact name. |
| GET /cards/:id | One card by its UUID. |
| GET /sets | Every set, with printing counts. |
| GET /sets/:code | One set by code, e.g. ogn. |
| GET /bulk-data | Index of the bulk exports. |
| GET /bulk/cards | The whole catalogue: 1725 printings, ~1.2 MB. |
| GET /bulk/prices | TCGplayer prices for 1664 printings. Refreshed daily. |
| GET /prices/:riftboundId | Prices for one printing. |
| GET /tags?kind=&q= | Community tags, most-used first. kind is function or art; q filters by name. |
| GET /tags/:kind/:slug | One tag: description, count, creator, and the search that lists its cards. |
| GET /cards/:id/tags | Every community tag on one printing: function tags from its card, art tags of its own. |
| GET /bulk/tags | Every tagging, one row per (tag, printing). What the site builds from. |
| GET /cards/:id/rulings | Rulings for the card, from Riftbound FAQ. The same list for every printing. |
| GET /bulk/rulings | Every ruling, one entry per card. What the site builds from. |
| GET /health | Liveness check. |
Searching
/cards/search takes the same query syntax as the site's search
box, documented in full on the syntax guide.
| Example | Finds |
|---|---|
| /cards/search?q=t:unit d:fury e<=3 | Cheap Fury units. |
| /cards/search?q=t:gear p:1 | Gear costing one rune. |
| /cards/search?q=s:ogn r:epic | Epics in Origins. |
Results are one printing per card by default: reprints and variants collapse into a single entry, and the rest are on that card's page. A query matching nothing returns 404, not an empty list.
Response shape
Lists are wrapped in an envelope:
{
"object": "list",
"total_cards": 41,
"has_more": false,
"next_page": null,
"data": [ /* card objects */ ]
} Errors use the same convention, with the HTTP status repeated in the body:
{
"object": "error",
"status": 404,
"code": "not_found",
"details": "Your query didn't match any cards. Adjust your search terms."
} The card object
| Field | Meaning |
|---|---|
| object | Always "card". |
| id | Permanent UUID for this printing. |
| printing_id | The same value as id, under the name /bulk/cards and /bulk/prices use. Join on this. |
| oracle_id | Permanent UUID shared by every printing of the same card. Also in /bulk/cards. |
| lang | Language of the text fields. Only "en" today. |
| name | Printed name, including any variant suffix, e.g. "Annie, Dark Child (Metal)". |
| oracle_name | The base name shared by every printing, e.g. "Annie, Dark Child". |
| type | Unit, Spell, Gear, Legend, Battlefield or Rune. |
| domains | Lowercased array. Also which runes may pay the rune cost. |
| energy | Energy cost. null when there is none. |
| power | Rune cost: how many runes are recycled to play it. null when there is none. |
| might | Combat stat on units. null otherwise. |
| keywords | Lowercased array. |
| tags | Lowercased array. Searchable with tag:. |
| rules_text | Plain text. Keeps :rb_*: symbol shortcodes. |
| flavor_text | Plain text, or null. |
| set | Set code, lowercased, e.g. "ogn". |
| set_name | Full set name. |
| collector_number | As printed, zero-padded, e.g. "017". Letter-prefixed (t, r, s) for tokens, runes and special promos. |
| rarity | common, uncommon, rare, epic, showcase or promo. |
| artist | Illustrator, or null. |
| variant | alternate, overnumbered, signature or null. Metal promos carry it in the name instead. |
| riftbound_id | Riot's own id, e.g. ogn-025-298. Not unique: 52 promos share one. |
| rifthunt_uri | Canonical path for this printing on rifthunt.com. |
| rulings_uri | Path to the card's rulings, /cards/:id/rulings. An empty list when there are none. |
| images | Object with small (200 wide), normal (480 wide) and large (744x1039) WebP URLs on images.rifthunt.com, plus back for the five double-sided tokens. Immutable: the ?v= changes when the image does. |
| tcg_id | TCGplayer product id, or null. Build your own link with it if you prefer. |
| finishes | The finishes this printing is made in: ["normal", "foil"], ["foil"] or ["normal"], the same names as the keys of prices. null when unknown (no TCGplayer product). |
| purchase_uris | Object with tcgplayer (an affiliate link, see below) and cardmarket. |
| prices | TCGplayer prices per finish, or null if we have none. See below. |
One printing or all of them
By default search returns one printing per card: the
plain one, without a variant suffix. Add
unique=prints to get every printing, which is what you want
for prices: a card and its Metal promo are separate products fifty times
apart in value.
curl -s "https://api.rifthunt.com/cards/search?q=annie&unique=prints" /cards/named?exact= accepts either form. The base name returns
the plain printing; a printed name such as Annie, Dark Child (Metal)
returns that printing.
Sorting
unique= is cards (default), prints, or art
for one printing per illustration. order= is one of name (default),
released, set, number, usd,
rarity, energy, power, might or artist.
dir= is asc, desc, or auto (default):
newest and priciest first, everything else A to Z. Cards with no value for the sort key
come last either way. next_page carries all three.
curl -s "https://api.rifthunt.com/cards/search?q=t:legend&unique=prints&order=usd" Bulk data
/bulk/cards returns all 1725 printings in one response,
about 1.2 MB. It is the same file the site itself builds from, so it will
never disagree with what you see here. Fetch it once a day at most, since
card data only changes when a set does.
curl -s https://api.rifthunt.com/bulk/cards > cards.json
Each printing there carries the same ids as the card object, under the same
names: printing_id (the card object's id) and
oracle_id, so you can group printings into cards, or match one
to an API result, without a second request. It also carries
finishes, as on the card object. The other fields are camelCase,
in the shape the site builds from.
Two fields there are deprecated and will be removed soon.
id is our ingest's source record id (like
ogn-001-298), not the card object's id; use
printing_id. oracleId is the same value as
oracle_id, kept for now for backwards compatibility; use
oracle_id.
Community tags
Cards carry two kinds of community tag: function
tags on the card (what it does, searchable as otag:removal) and
art tags on a printing (what the picture shows, art:dragon).
Reading them needs no account. Adding them does: sign in on the tagger, which uses the same API with a bearer token.
Tags can change at any time, so cache them for minutes, not days.
curl -s "https://api.rifthunt.com/cards/search?q=otag:removal" Rulings
Rulings come from Riftbound FAQ,
Christian “Near” Ivicevic's unofficial rulings site, under CC BY-SA 4.0:
167 rulings on 71 cards right now. Every response names the source, the
upstream commit and the licence; if you republish them, keep the attribution. Each ruling is a
question and an answer, the answer as plain text (comment) and as HTML that uses the
same :rb_*: shortcodes and [Keyword] tokens as rules_text.
Rulings belong to the card, so every printing returns the same list. A wrong ruling is reported on
the FAQ's GitHub, not to us.
curl -s https://api.rifthunt.com/bulk/rulings > rulings.json Prices
Prices are a separate export, because they change on a completely different
schedule to the catalogue. /bulk/prices returns 1688 rows,
one per printing with a TCGplayer product, of which 1664 have
a current market price. The rest are listed products with nothing for sale
right now, so every field is null. Refreshed daily.
curl -s https://api.rifthunt.com/bulk/prices > prices.json
Normal and foil are reported separately, under finishes, because
TCGplayer lists them as separate products and they diverge by orders of
magnitude: the same card can be seven cents normal and $185 foil.
Every row reports both finishes, including ones the card is never made in.
Check a printing's finishes to tell them apart: a finish listed
there with null prices exists but has no listings, and a finish
missing from it does not exist (most rares and up are foil only).
Each row also carries a purchaseUri, an affiliate deep link to
that exact printing on TCGplayer. See affiliate links.
Each row carries the printing's printing_id, the same value as
in /bulk/cards and on the card object, so that is the simplest
way to join a price to its card.
Rows are also keyed by riftboundId, collector and
slug together, never by riftboundId alone. The 52
“(Metal)” promos share an id with their base printing and are
separate products at very different prices, so keying on the id by itself
will silently give you the wrong one.
Affiliate links
The purchase_uris.tcgplayer value on every card, and the
purchaseUri on every price row, are affiliate links. RiftHunt
earns a commission when someone buys through one. They are how this API
stays free and keyless, and you are welcome to use them in your own app.
Caching
Responses are cached at Cloudflare's edge, so most requests never reach the origin. Respect these and you will rarely notice a limit exists.
| Endpoint | Browser | Edge |
|---|---|---|
| /cards/search | 60s browser | 1h edge, 24h stale-while-revalidate |
| /cards/:id, /cards/named | 1h browser | 24h edge |
| /sets, /sets/:code | 1h browser | 24h edge |
| /bulk/cards | 1h browser | 24h edge, 7d stale-while-revalidate |
| /bulk/rulings, /cards/:id/rulings | 1h browser | 24h edge, 7d stale-while-revalidate |
| /bulk/prices, /prices/:id | 5–10m browser | 15–30m edge, 24h stale-while-revalidate |
| /tags, /cards/:id/tags, and any search using otag: or art: | 30s browser | 1m edge, 5m stale-while-revalidate |
Examples
# shell
curl -s "https://api.rifthunt.com/cards/search?q=t:gear%20p:1"
# PowerShell: note curl is an alias for Invoke-WebRequest, so use the native cmdlet
Invoke-RestMethod "https://api.rifthunt.com/sets" | Select-Object -ExpandProperty data
# browser / Node
const res = await fetch("https://api.rifthunt.com/cards/named?exact=Blind Fury");
const card = await res.json();
console.log(card.energy, card.power, card.domains); Terms
Free for any use, commercial included. RiftHunt is unofficial Fan Content under Riot Games' Legal Jibber Jabber policy: card names, text and images are Riot's, and your project inherits the same terms. A link back is appreciated but not required.