ID prefixes
| Prefix | Resource | Example | Stable across reprints? |
|---|---|---|---|
sr- | Series | sr-10 | n/a |
st- | Set | st-53 | n/a |
cd- | Printing | cd-1813 | n/a |
et- | Card (Entity) | et-100 | Yes |
el- | Creature | el-159 | Yes |
ble- | Banlist entry | ble-1 | Yes |
rul- | Ruling | rul-1 | Yes |
- Card and Creature IDs are forever. The
et-100that’s Pyrotter today will be Pyrotter on the day the API is sunset. New artwork, new printings, new banlist updates — the sameet-100. - Printing IDs are also stable, but a Card can pick up new Printing IDs over time as it gets reprinted.
- Banlist and Ruling IDs are stable for as long as the entry exists. If a ruling is superseded, its ID is retired (not reused) and a new ruling with a new ID takes its place.
Set codes vs Set IDs
Sets have two identifiers, and they’re different:id— the API identifier. What you pass in URLs:GET /v1/sets/st-53.abbr— the human-friendly code, typically two to four uppercase letters. What appears on the bottom of physical cards. Use this for display, not for lookups.
series.code is the human-friendly Roman-numeral or short code; series.id is the API identifier).
Printing collector numbers
A printing has three number-ish fields, only one of which is the API identifier:| Field | Example | What it is |
|---|---|---|
id | cd-1813 | The API identifier. Use this in URLs. |
set_number | 100/180 | Printed on the card. Position within the set. |
sort_number | 100 | Numeric form of set_number for stable ordering across reprints. |
set_number (not id). The list endpoint’s ?set_number= filter takes that exact format.
Internal IDs we don’t expose
The PlanetScale database has its own internal IDs — primary keys generated for normalized tables, foreign-key columns, etc. None of those leak into the public API. If you see an integer where a string ID would normally appear, that’s a bug — open a ticket with therequest_id.
The only reason this matters: don’t try to reverse-engineer the suffix as a primary key from an internal system. The numeric portion is monotonic but not contiguous (gaps appear when rows are deleted or merged) and not stable across migrations.
ID formats are validated
The router validates ID format before any database lookup. A request with a malformed ID short-circuits to anot_found without consuming a database round-trip: