Identifiers
UpdatedEvery card and variant now carries two identifiers: a stable UUID (recommended) and a human-readable slug (legacy). This page explains both, how slugs are composed, and what changes in v2.
uuid field on cards and variants and use it as your primary key. The existing id (a slug) keeps working and remains useful as a human-readable label, but it is no longer the recommended way to reference a card.Two identifiers, one card
We are migrating identity from slug-based IDs to UUIDs for both cards and variants. Slugs are derived from mutable text (names, sets, rarities), so they are not stable. Upstream renames and edge cases caused collisions and duplicates over time. UUIDs are content-addressed and never change.
uuidRecommendedStable, globally-unique, and deterministic. The canonical key we upsert on internally. Prefer this for storage, joins, and lookups.
f8c3de3d-1fea-5d7c-a8b0-29f63c4c3454idLegacy / slugHuman-readable and great for debugging or URLs. Still returned and still queryable, but can change and is not recommended as a primary key.
pokemon-battle-academy-fire-energy-22-charizard-stampedSlugs (legacy, human-readable)
A slug is a composite identifier: several source fields are individually sanitized, slugified, and joined with dashes. The card slug is built from game · set · name · rarity; a variant slug appends the normalized condition and printing after an underscore.
Anatomy of a slug
Example: pokemon-battle-academy-fire-energy-22-charizard-stamped-promo
game
The game the card belongs to.
set
Slugified set name.
name
Card name, including parenthetical qualifiers.
rarity
Slugified rarity (e.g. common, uncommon, rare, promo).
A variant slug extends the card slug with its condition and printing, e.g. …charizard-stamped-promo_near-mint.
How each segment is generatedAdvanced — only needed if you reconstruct slugs yourself
Every text field passes through the same two steps before being joined. If you reconstruct slugs on your end, mirror this order exactly.
- 1. Sanitize special characters.A handful of characters that slugification would otherwise silently strip are first rewritten to a word, so meaningfully different cards don't collapse to the same slug (see the table below).
- 2. Slugify. Lowercase and trim → apostrophes become dashes → remaining punctuation (
. , ! ? : ; ( )) is removed → spaces become dashes → any non-word characters are dropped → repeated dashes collapse to one → leading/trailing dashes are trimmed.
Special-character mapping
These substitutions are applied to all text fields (name, rarity, etc.) before slugification. They are what keep Unown (?) and Unown (!), or the asterisk alt-art markers Mega Man* and Mega Man**, from colliding.
| Character | Replaced with | Example |
|---|---|---|
| ? | " question" | Unown (?) → …unown-question |
| ! | " exclamation" | Unown (!) → …unown-exclamation |
| + | " plus" | Energy+ → …energy-plus |
| * | " star" | Mega Man* → …mega-man-star |
Condition normalization
For variant slugs, the raw condition is first normalized to a canonical value before slugification. Any grade suffix is dropped to its base — Near Mint (Holofoil) becomes Near Mint — and sealed product collapses to Sealed.
// Sealed / unopened product → "Sealed"
// Otherwise, collapse any suffix to the base grade:
"Near Mint" // "Near Mint …" → "Near Mint"
"Lightly Played" // "Lightly Played …" → "Lightly Played"
"Moderately Played"// "Moderately Played …"→ "Moderately Played"
"Heavily Played" // "Heavily Played …" → "Heavily Played"
"Damaged" // "Damaged …" → "Damaged"Preparing for API v2
In v2, UUIDs become the primary idon both objects, and today's slug-based IDs move to a dedicated slug field. Adopting uuid now means a one-line rename when you upgrade.
| v1 (today) | v2 | Notes |
|---|---|---|
| card.id | card.slug | Human-readable slug, now demoted to a secondary field. |
| card.uuid | card.id | The stable UUID becomes the canonical card ID. |
| variant.id | variant.slug | Human-readable variant slug. |
| variant.uuid | variant.id | The stable UUID becomes the canonical variant ID. |
uuid field. Migrate at your own pace by reading uuid now, so the eventual switch to v2 is just id → slug and uuid → id.