TopDeck.gg API

Complete reference for TopDeck.gg's tournaments API. Access data on tournaments, players, and standings. Seamlessly integrate tournament data into your projects.

v2
Tournaments · Players · Standings · Decklists · Free REST API

Usage Requirements

The TopDeck.gg API is free to use, providing tournament data for your projects and applications.

Rate Limits

Most endpoints allow 100 requests per minute. Heavier endpoints like bulk tournament queries have lower limits. You'll receive a 429 response if you exceed your limit. Need more? E-mail us at [email protected].

Attribution Required

Any project using the API must include a visible credit and link back to TopDeck.gg. See the attribution example on the right.

Info
By using the API, you agree to these requirements. Thank you for supporting TopDeck.gg!
Quick Start
curl https://topdeck.gg/api/v2/tournaments \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"game": "Magic: The Gathering", "format": "Standard", "start": 1700000000}'
Attribution Example
<p>Data provided by
  <a href="https://topdeck.gg"
     target="_blank">
    TopDeck.gg
  </a>
</p>
POST/v2/tournaments

Search completed tournaments. Returns standings, decklists, and optional round data. Filter by TID, or by game + format + date range.

Request Body

Use either TID mode (specific IDs) or query mode (filters). game and format are required in query mode.

FieldTypeDescription
TIDstring | string[]Tournament ID or array of IDs. Disables query-mode filters.
gamestringGame name. Case sensitive.
formatstringGame format. Case sensitive.
startintegerEarliest tournament start date (unix seconds).
endintegerLatest tournament start date (unix seconds).
lastintegerDays back from today. Alternative to start / end.
participantMinintegerMinimum participant count.
participantMaxintegerMaximum participant count.
columnsstring[]Player fields to include on standings. See allowed values below.
roundsboolean | string[]Include round data. true is shorthand for ["round", "tables"]. Default false.
tablesstring[]Table fields to include when rounds is set. See allowed values below.
playersstring[]Player fields within table rows when rounds is set. See allowed values below.
Allowed values
FieldDefaultValid values
columnsdecklist, wins, draws, lossesname, id, decklist, wins, winsSwiss, winsBracket, winRate, winRateSwiss, winRateBracket, byes, draws, losses, lossesSwiss, lossesBracket
tablestable, players, winner, statustable, players, winner, status
playersname, idname, id, decklist

Including decklist in columns or players also returns deckObj when structured deck data is available.

Pass exactly as written (case sensitive).

GameFormat
Magic: The Gathering
  • EDH
  • Pauper EDH
  • Standard
  • Pioneer
  • Modern
  • Legacy
  • Pauper
  • Vintage
  • Premodern
  • Sealed
  • Limited
  • Duel Commander
  • Old School 93/94
  • Canadian Highlander
  • Tiny Leaders
  • EDH Draft
  • Timeless
  • Historic
  • Explorer
  • 7pt Highlander
  • Oathbreaker
Pokemon
  • Standard
  • Expanded
  • Legacy
  • GLC
Yu-Gi-Oh
  • Edison
  • Goat
  • Advanced
  • HAT
  • REDU
  • Genesys
  • Domain
One PieceLeave format blank ("")
Gundam TCGLeave format blank ("")
Union ArenaLeave format blank ("")
Star Wars Unlimited
  • Premier
  • Draft
  • Twin Suns
Disney Lorcana
  • Core Constructed
  • Infinity Constructed
  • Sealed
  • Pack Rush
Riftbound
  • Constructed
  • 2v2
  • Free-for-All
Marvel SnapLeave format blank ("")
Overpower
  • Modern
  • Draft
  • Sealed
  • Legacy Mixed
  • Modern Skirmish
  • Legacy Skirmish
Naruto Mythos TCG
  • Release Event
  • Pre-Release Event
  • Local Tournament
  • Store Championship
  • Regional
Cyberpunk TCGLeave format blank ("")
Chrono Core TCG
  • Launch Event
  • Weekly Arena
  • Crossfire
  • Realm Showdown
  • Realm Championship
Beyblade
  • X
Cardfight Vanguard
  • Standard
  • Premium
  • VPremium
DigimonLeave format blank ("")
Flesh and BloodLeave format blank ("")
Shadowverse: EvolveLeave format blank ("")
Sorcery: Contested RealmLeave format blank ("")
Altered
  • Standard
  • Draft
CookieRun: Braverse TCG
  • Casual
  • Constructed
  • Brave League
  • Draft
  • Sealed
  • Learn to Play
  • Pre-Release
Rush of Ikorr
  • Standard
Lairen: La HistoriaLeave format blank ("")
Five MicsLeave format blank ("")
Settlers of CatanLeave format blank ("")
GudnakLeave format blank ("")
Hadrai'da Ascendant
  • Conquest Duel
  • Conquest Tag Team
  • Conquest Squads
  • Conquest Battle Royale
  • Gladiator Duel
  • Gladiator Tag Team
  • Gladiator Squads

Response Fields

Tournament Level
FieldTypeDescription
TIDstringTournament identifier
tournamentNamestringName of the tournament
swissNumnumberNumber of Swiss rounds played
startDatenumberUnix timestamp of tournament start
gamestringGame being played
formatstringGame format
topCutnumberSize of the top cut bracket (0 if none)
eventDataobjectLocation details (lat, lng, city, state, address, headerImage)
standingsarrayPlayer standings (based on columns param)
roundsarrayRound data (when rounds param is included)
Request
{
  "game": "Magic: The Gathering",
  "format": "EDH",
  "last": 30,
  "columns": ["name", "decklist", "wins", "draws", "losses"],
  "rounds": true
}
Response
[
  {
    "TID": "abc123",
    "tournamentName": "Weekly EDH",
    "swissNum": 5,
    "startDate": 1627844461,
    "game": "Magic: The Gathering",
    "format": "EDH",
    "topCut": 8,
    "eventData": {
      "city": "New York",
      "state": "NY",
      "address": "Local Game Store"
    },
    "standings": [
      {
        "name": "Player Name",
        "decklist": "~~Commanders~~\n...",
        "wins": 4,
        "draws": 1,
        "losses": 0
      }
    ],
    "rounds": [
      {
        "round": 1,
        "tables": [
          {
            "table": 1,
            "players": [
              { "name": "Alice", "id": "abc" },
              { "name": "Bob", "id": "def" }
            ],
            "winner": "Alice",
            "winner_id": "abc",
            "status": "Completed"
          }
        ]
      }
    ]
  }
]
GET/v2/tournaments/{TID}

Full tournament data: metadata, standings, and all rounds in one response.

Conditional Fields

  • Decklists: Only when tournament has ended OR organizer enabled "Show Decks"
  • deckObj: Only when structured deck data is available
  • Discord fields: Only when tournament includes Discord info
  • Win rate fields: League tournaments use successRate instead of winRate

Response Fields

Top Level
FieldTypeDescription
dataobjectTournament metadata. See fields below.
standingsarrayPlayer standings. See standings for field shape.
roundsarrayAll rounds. See rounds for field shape.
data
FieldTypeDescription
tidstringTournament ID.
namestringTournament name.
gamestringGame.
formatstringGame format.
startDatenumberUnix timestamp of start.
Response
{
  "data": {
    "tid": "abc123",
    "name": "Tournament Name",
    "game": "Magic: The Gathering",
    "format": "EDH",
    "startDate": 1627844461
  },
  "standings": [
    {
      "standing": 1,
      "name": "Player Name",
      "id": "abc123",
      "points": 15,
      "winRate": 0.8,
      "opponentWinRate": 0.6
    }
  ],
  "rounds": [
    {
      "round": 1,
      "tables": [
        {
          "table": 1,
          "players": [
            { "name": "Alice", "id": "abc123" },
            { "name": "Bob", "id": "def456" }
          ],
          "winner": "Alice",
          "winner_id": "abc123",
          "status": "Completed"
        }
      ]
    }
  ]
}
GET/v2/tournaments/{TID}/info

Tournament metadata, schedule, and location.

Response Fields

FieldTypeDescription
tidstringTournament ID
namestringTournament name
gamestringGame being played
formatstringGame format
startDatenumberUnix timestamp of start
endDatenumber | nullUnix timestamp of end
statusstringComplete, Ongoing, or Not Started
locationobject | nullLocation details (name, city, state, country, lat, lng)
headerImagestring | nullURL of event header image
Response
{
  "tid": "abc123",
  "name": "Tournament Name",
  "game": "Magic: The Gathering",
  "format": "EDH",
  "startDate": 1627844461,
  "endDate": 1627855261,
  "status": "Complete",
  "location": {
    "name": "Card Kingdom Seattle",
    "city": "Seattle",
    "state": "WA",
    "country": "US"
  },
  "headerImage": "https://..."
}
GET/v2/tournaments/{TID}/standings

Standings for a tournament. League tournaments report successRate instead of winRate. Pairs-mode tournaments additionally include gameWinRate.

Conditional Fields

  • Decklists: Only when tournament has ended OR organizer enabled "Show Decks"
  • deckObj: Only when structured deck data is available
  • Discord fields: Only when tournament includes Discord info
  • Win rate fields: League tournaments use successRate / opponentSuccessRate
  • Game win rates: Only in Pairs mode tournaments (gameWinRate, opponentGameWinRate)
Response
[
  {
    "standing": 1,
    "name": "Player Name",
    "id": "abc123",
    "decklist": "~~Commanders~~\n...",
    "deckObj": { "Commanders": {}, "Mainboard": {} },
    "points": 15,
    "winRate": 0.83,
    "opponentWinRate": 0.7
  }
]
GET/v2/tournaments/{TID}/players/{ID}

Player details and match record.

Conditional Fields

  • Decklists: Only when tournament has ended OR organizer enabled "Show Decks"
  • deckObj: Only when structured deck data is available

Response Fields

FieldTypeDescription
namestringDisplay name.
standingnumberTournament standing.
deckliststring | nullDecklist text or URL.
deckObjobject | nullStructured deck data.
winRatenumberOverall win rate (0.0–1.0).
gamesPlayednumberTotal games played.
gamesWonnumberGames won.
byesnumberByes received.
gamesDrawnnumberGames drawn.
gamesLostnumberGames lost.
Response
{
  "name": "Player Name",
  "standing": 1,
  "decklist": "~~Commanders~~\n...",
  "deckObj": { "Commanders": {}, "Mainboard": {} },
  "winRate": 0.83,
  "gamesPlayed": 10,
  "gamesWon": 8,
  "byes": 0,
  "gamesDrawn": 1,
  "gamesLost": 1
}
GET/v2/tournaments/{TID}/rounds

List every round of a tournament, each with its tables and results. Returns an array of round objects.

Conditional Fields

  • Decklists: Only when tournament has ended OR organizer enabled "Show Decks"
  • deckObj: Only when structured deck data is available
  • Discord fields: Only when tournament includes Discord info

Response Fields

Round
FieldTypeDescription
roundnumber | stringRound number, or bracket label like "Top 8".
tablesarrayTables played this round. See fields below.
Table
FieldTypeDescription
tablenumber | "Byes"Table number, or "Byes" for the bye row.
playersarrayPlayers seated. See player details for field shape.
winnerstring | nullWinner's name, or null for draws or unfinished.
winner_idstring | "Draw" | nullWinner's ID, "Draw" for ties, null for unfinished.
statusstringCompleted, Active, Pending, or Bye.
Response
[
  {
    "round": 1,
    "tables": [
      {
        "table": 1,
        "players": [
          { "name": "Player 1", "id": "abc" },
          { "name": "Player 2", "id": "def" }
        ],
        "winner": "Player 1",
        "winner_id": "abc",
        "status": "Completed"
      }
    ]
  },
  {
    "round": "Top 8",
    "tables": [{ ... }]
  }
]
GET/v2/tournaments/{TID}/rounds/latest

Tables from the current/latest round. Returns a flat array of tables — no round wrapper, unlike /rounds.

Conditional Fields

  • Decklists: Only when tournament has ended OR organizer enabled "Show Decks"
  • deckObj: Only when structured deck data is available
  • Discord fields: Only when tournament includes Discord info

Response Fields

Each element is a table. Same shape as the tables entries on /rounds:

FieldTypeDescription
tablenumber | "Byes"Table number, or "Byes" for the bye row.
playersarrayPlayers seated.
winnerstring | nullWinner's name, or null for draws or unfinished.
winner_idstring | "Draw" | nullWinner's ID, "Draw" for ties, null for unfinished.
statusstringCompleted, Active, Pending, or Bye.
Response
[
  {
    "table": 1,
    "players": [
      { "name": "Player 1", "id": "abc" },
      { "name": "Player 2", "id": "def" }
    ],
    "winner": "Player 1",
    "winner_id": "abc",
    "status": "Completed"
  },
  {
    "table": "Byes",
    "players": [
      { "name": "Player 5", "id": "ghi" }
    ],
    "status": "Bye"
  }
]
GET/v2/tournaments/{TID}/attendees

All tournament attendees: registered players, dropped players, and waitlisted users.

Staff Only
Requires judge role or higher.

Response Fields

FieldTypeDescription
uidstring | nullUser ID. null for unregistered waitlist entries.
namestringDisplay name.
emailstring | nullEmail address.
discordstring | nullDiscord username.
discordIdstring | nullDiscord user ID.
statusstringplayer, dropped, or waitlist.
standingnumber | nullTournament standing. null for dropped or waitlist.
deckliststring | nullDecklist URL or text.
deckObjobject | nullStructured deck data.
Waitlist-Specific Fields

Additional fields for entries with status: "waitlist":

FieldTypeDescription
joinedAtnumber | nullUnix timestamp when the user joined the waitlist.
waitlistStatusstringwaiting, offered, accepted, declined, or expired.
waitlistPositionnumber | nullQueue position. Only set when waitlistStatus: "waiting".
offeredAtnumber | nullUnix timestamp when the spot was offered.
expirationTimestampnumber | nullUnix timestamp when the offer expires.
Response
[
  {
    "uid": "player123",
    "name": "John Doe",
    "email": "[email protected]",
    "status": "player",
    "standing": 1,
    "decklist": "~~Commanders~~\n...",
    "deckObj": { "Commanders": {}, "Mainboard": {} }
  },
  {
    "uid": "dropped456",
    "name": "Jane Smith",
    "email": "[email protected]",
    "status": "dropped",
    "standing": null
  },
  {
    "uid": "waitlist789",
    "name": "Bob Wilson",
    "email": "[email protected]",
    "status": "waitlist",
    "waitlistStatus": "waiting",
    "waitlistPosition": 1,
    "joinedAt": 1627840000
  }
]
POST/v2/tournaments/{TID}/register

Register one or more players by email. Emails matching an account are registered immediately; emails without an account receive an invitation and convert on signup. Returns 409 if the request would exceed the event's player cap — pass overrideCap: true to bypass.

Staff Only
Requires admin role or higher.

Request Body

FieldTypeDescription
emailsstring | string[]Email or array of emails. Required.
overrideCapbooleanSkip the capacity check. Defaults to false.

Response Fields

Each input email appears in exactly one bucket, lowercased.

FieldTypeDescription
addedstring[]Newly registered.
pendingstring[]No account found; invitation sent.
alreadyRegisteredstring[]Already registered or invited. No-op.
failedstring[]Could not be processed.
bannedstring[]Banned by this organizer. Skipped.
capacitynumber | nullEvent player cap, or null if unset.
registeredCountnumberTotal registered: confirmed, pending invites, and offered waitlist seats.
Request
{
  "emails": ["[email protected]", "[email protected]"],
  "overrideCap": false
}
Response
{
  "added": ["[email protected]"],
  "pending": ["[email protected]"],
  "alreadyRegistered": [],
  "failed": [],
  "banned": [],
  "capacity": 32,
  "registeredCount": 24
}
GET/v2/me/tournaments

List tournaments owned by your API key. Defaults to tournaments with a future start date; pass filter=all to include in-progress and past events.

Note
Requires an active TopDeck subscription.

Query Parameters

ParameterTypeDefaultDescription
filterstringupcomingSet to all to include in-progress and past tournaments.

Response Fields

FieldTypeDescription
tidstringTournament ID
namestringTournament name
gamestringGame being played
formatstringGame format
startDatenumberUnix timestamp of start
endDatenumber | nullUnix timestamp of end
statusstringComplete, Ongoing, or Not Started
locationobject | nullLocation details (name, city, state, country, lat, lng)
headerImagestring | nullURL of event header image
registeredCountnumber | nullCurrent registered player count (null if event has no registration data)
capacitynumber | nullParticipant cap for the event (null if uncapped)
Response
[
  {
    "tid": "abc123",
    "name": "Weekly Modern",
    "game": "Magic: The Gathering",
    "format": "Modern",
    "startDate": 1627844461,
    "endDate": 1627855261,
    "status": "Not Started",
    "location": {
      "name": "Card Kingdom Seattle",
      "city": "Seattle",
      "state": "WA",
      "country": "US"
    },
    "headerImage": "https://...",
    "registeredCount": 24,
    "capacity": 32
  }
]

Error Codes

The API uses standard HTTP status codes. Errors return a JSON body with a single error field describing what went wrong.

CodeMeaningWhen
400Bad RequestMissing or invalid parameters
401UnauthorizedInvalid or missing API key
403ForbiddenValid API key but insufficient permissions on the tournament
404Not FoundTournament (or other referenced resource) doesn't exist
409ConflictAction would violate a constraint (e.g. register past player cap)
429Rate LimitedToo many requests per minute
500Server ErrorInternal error — contact us
400 Bad Request
{ "error": "Both \"game\" and \"format\" fields are required." }
401 Unauthorized
{ "error": "Invalid API key" }
403 Forbidden
{ "error": "Forbidden: Insufficient permissions" }
404 Not Found
{ "error": "Tournament not found" }
409 Conflict
{ "error": "Event would exceed capacity (32/32 registered, 2 requested, 0 available). Set overrideCap: true to bypass." }
429 Rate Limited
{ "error": "Rate limit exceeded", "retryAfterSeconds": 42 }

Also includes a Retry-After header with the seconds to wait.

500 Server Error
{ "error": "Internal server error" }
Top