API
ShuffleReady's public API says whether a Magic: The Gathering deck is legal in a format and why not, today or on any past date, using each format's dated rules and ban lists (Commander back to 2002). It's free, with no key: up to 30 requests a minute per IP, and 10 for decks given as a link.
- OpenAPI description of every endpoint and field
- llms.txt , the same for language models
Use with Claude or ChatGPT
The MCP server lets a chatbot or agent check decks for you: "is this deck legal in Commander?", "what was banned in EDH in 2007?". Add its url as a custom connector (in Claude: Settings, Connectors, Add custom connector; in ChatGPT: a connector in developer mode). It needs no sign in.
https://shuffleready.com/mcpIts tools only read:
check_deck_legality: Is a deck legal in up to 5 formats, today or on a date?list_formats: The format slugs.format_rules_on_date: A format's checks and its banned, restricted and banned as commander cards on a date.card_legality: Is a card legal in each official format, and why not?
Check a deck
POST /api/v1/legality with a JSON body. Is this deck legal in Commander today?
curl -s https://shuffleready.com/api/v1/legality \
-H 'content-type: application/json' \
-d '{"deck":"Commander\n1 Kenrith, the Returned King\nDeck\n1 Sol Ring\n1 Mana Crypt","formats":["commander"]}'GET /api/v1/legality takes the same as query parameters, for short decks:
curl -s 'https://shuffleready.com/api/v1/legality?deck=4%20Lightning%20Bolt%0A4%20Brainstorm&format=vintage&format=legacy'Request
| Field | Type | Description |
|---|---|---|
deck | string | The deck list, one card per line (1 Sol Ring, 4x Lightning Bolt), with lines like Commander or Sideboard starting a category, at most 250 lines. Or a link to a deck on Moxfield, Archidekt and similar sites. |
formats | array of slugs or ids | 1 to 5 formats: slugs from the list below, or a format's id (the number in its page's url). By GET, format=, repeated. |
asOf | string, optional | Check the deck as of a date: YYYY-MM-DD, YYYY-MM (the month's last day) or YYYY (December 31). Today without one. |
allowNewCards | boolean, optional | With asOf: that date's rules and ban lists, but cards printed after it are allowed (and listed in deck.printedAfterAsOf). |
Response
| Field | Description |
|---|---|
asOf | The date checked (YYYY-MM-DD), or null. |
deck.cards | Copies of the cards that matched a card name. |
deck.unresolved | Lines whose name matched no card, with suggestions. The other cards are still checked. |
results[].legal | true when the deck passes every check of the format. |
results[].status | LEGAL, FAILED_CHECKS, or INVALID_CARDS when a name matched no card. |
results[].errors | Each failed check: its description, the cards that fail it with the reason for each, and messages (a deck's size, say). |
results[].tier | The Commander bracket, for Commander's brackets. |
results[].error | When the format couldn't be checked, ex: FORMAT_NOT_YET_PUBLISHED for a date before its first rules, with its firstDate. |
links.checkOnSite | The format's page on ShuffleReady. |
{
"asOf": "2007-12-31",
"allowNewCards": false,
"deck": { "cards": 2, "unresolved": [] },
"results": [
{
"format": { "id": 32, "slug": "commander", "name": "Commander" },
"formatVersion": { "id": 9900, "effectiveFrom": "2006-02-01" },
"legal": false,
"status": "FAILED_CHECKS",
"tier": null,
"errors": [
{
"check": "NOT_YET_PRINTED",
"description": "Cards printed after 2007-12-31",
"cards": [
{
"name": "Jeweled Lotus",
"reason": "Not yet printed on 2007-12-31 (first printed 2020-11-20)"
}
],
"messages": []
}
]
}
],
"links": { "checkOnSite": "https://shuffleready.com/format/1/32/commander" }
} Errors are { "error": { "code", "message" } } :
BAD_REQUEST (400): The input, and what's wrong.UNKNOWN_FORMAT (404): A format no slug or id names, with the slugs.DECK_URL_FAILED (400): The deck's link didn't load: send its text instead.RATE_LIMITED (429): Over the limit: try again in a minute.BUSY, TIMEOUT (503): Too many checks at once, or one took too long.
On a past date
With asOf , the format's rules and ban lists in effect on that date apply, and cards printed after it fail as not yet printed. Was this deck legal in EDH at the end of 2007?
curl -s https://shuffleready.com/api/v1/legality \
-H 'content-type: application/json' \
-d '{"deck":"1 Sol Ring\n1 Jeweled Lotus","formats":["edh"],"asOf":"2007"}' Add allowNewCards to play by 2007's ban list with today's cards:
curl -s https://shuffleready.com/api/v1/legality \
-H 'content-type: application/json' \
-d '{"deck":"1 Sol Ring\n1 Jeweled Lotus","formats":["edh"],"asOf":"2007","allowNewCards":true}'Formats
Name a format by its slug, or one of its other names. GET /api/v1/formats lists them:
| Slug | Format | Rules from |
|---|---|---|
commander (also edh, elder-dragon-highlander) | Commander | 2002-10-01 |
commander-bracket-1-exhibition | Commander Bracket 1: Exhibition | 2025-02-11 |
commander-bracket-2-core | Commander Bracket 2: Core | 2025-02-11 |
commander-bracket-3-upgraded | Commander Bracket 3: Upgraded | 2025-02-11 |
commander-bracket-4-optimized | Commander Bracket 4: Optimized | 2025-02-11 |
commander-bracket-5-cedh (also cedh) | Commander Bracket 5: cEDH | 2025-02-11 |
legacy (also type-1-5) | Legacy | 2004-09-01 |
modern | Modern | 2011-08-01 |
oathbreaker | Oathbreaker | 2019-05-01 |
old-school-93-94 | Old School 93/94 | 2019-09-07 |
pauper-commander (also pdh, pauper-edh) | Pauper Commander | 2019-06-01 |
pioneer | Pioneer | 2019-10-01 |
premodern | Premodern | 2023-07-01 |
standard-brawl | Standard Brawl | 2018-05-10 |
tiny-leaders-reborn (also tiny-leaders) | Tiny Leaders: Reborn | 2026-10-05 |
vintage (also type-1) | Vintage | 1994-01-01 |
Any other public format on ShuffleReady can be named by its id. Questions or a format missing? See the contact page .