Submit Results

API Documentation

Access tournament results, decklists, stores, scenes, and card data.

Base URL https://api.digilab.cards

Overview

The DigiLab API provides read-only access to tournament data, decklists, store listings, scene information, and card data for the Digimon TCG competitive community.

Looking to build a Discord bot, meta tracker, or community tool?

The API is free for non-commercial use. Request an API key to get started.

What's available

  • Tournament listings — event dates, formats, player counts, winners, winning decks
  • Decklists — player submissions with archetype, placement, and tournament context
  • Stores — game store directory with locations and scene associations
  • Scenes — geographic regions (metro areas, states, countries)
  • Deck archetypes — archetype info, colors, display cards
  • Cards — card search with set, color, and type filters

What's not available

Player profiles, ratings, leaderboard rankings, and metagame analysis are not available via the API. These are exclusive to digilab.cards.

Conventions

  • All endpoints are GET requests that return JSON
  • Responses include standard Cache-Control headers (15 min edge cache for listings)
  • Paginated endpoints return a pagination object with page, per_page, total, and total_pages
  • Listing endpoints include extra metadata (stats, formats, event_types) only on page 1 to reduce payload size
  • Null values are included in responses (not omitted)

Quick Start

Make your first API request in 30 seconds.

1. Get an API key

Request one in the #api channel on Discord.

Join Discord

2. Make a request

curl -H "X-API-Key: dl_k_your_key_here" \
  "https://api.digilab.cards/api/tournaments?per_page=2"

3. Get data back

{
  "data": [
    {
      "tournament_id": 1234,
      "event_date": "2026-04-15",
      "event_type": "locals",
      "format": "BT18",
      "player_count": 16,
      "store_name": "Card Masters",
      "winner_name": "PlayerName",
      "winning_deck": "Blue Flare"
    }
  ],
  "pagination": { "page": 1, "per_page": 2, "total": 342, "total_pages": 171 }
}

That's it. All endpoints follow this same pattern — pass your key in the X-API-Key header, get JSON back.

Authentication

All API requests from external consumers require an API key. Pass it via the X-API-Key header:

curl -H "X-API-Key: dl_k_your_key_here" \
  https://api.digilab.cards/api/tournaments

Getting an API key

API keys are issued by DigiLab admins. To request one, reach out in the #api channel with:

  • What you're building (bot, website, tool, etc.)
  • Expected request volume
  • Your contact info
Keep your key secret.

Keys are shown once at generation and cannot be retrieved later. Do not commit keys to public repositories.

Rate Limits

Two rate limits apply to all API requests:

LimitWindowScope
60 requestsper minutePer IP address
300 requestsper minutePer API key

When rate limited, the API returns 429 Too Many Requests with a Retry-After header:

HTTP/1.1 429 Too Many Requests
Retry-After: 45
Content-Type: application/json

{"error": "Rate limit exceeded. Please slow down."}

Errors

All error responses return JSON with an error field:

{ "error": "Resource not found" }
StatusMeaningCommon Cause
400Bad RequestInvalid or missing query parameters
401UnauthorizedMissing X-API-Key header
403ForbiddenInvalid, revoked, or inactive API key
404Not FoundInvalid ID or slug in path (e.g. /api/store/99999)
429Too Many RequestsRate limit exceeded — check Retry-After header
500Server ErrorUnexpected failure — please report on Discord

Error response example

HTTP/1.1 404 Not Found
Content-Type: application/json

{ "error": "Store not found" }
HTTP/1.1 401 Unauthorized
Content-Type: application/json

{ "error": "API key required. Pass your key via the X-API-Key header." }

GET /api/tournaments

Paginated tournament listings with filtering and sorting.

Query parameters

ParamTypeDescription
pageintPage number. Default: 1
per_pageintResults per page. Default: 50, max: 100
scenestringFilter by scene slug (e.g. austin-tx)
countrystringFilter by country code (e.g. US, JP)
statestringFilter by state/region (e.g. TX)
continentstringFilter by continent (e.g. North America)
formatstringFilter by format ID (e.g. BT18)
event_typestringFilter by event type. Repeatable for multi-select. Values: locals, regional, major, online
searchstringSearch store names
date_fromstringStart date (YYYY-MM-DD)
date_tostringEnd date (YYYY-MM-DD)
sortstringSort field. Default: date. Values: date, player_count, event_type, store, format
sort_dirstringSort direction. Default: desc. Values: asc, desc

Response

{
  "data": [
    {
      "tournament_id": 1234,
      "event_date": "2026-04-15",
      "event_type": "locals",
      "format": "BT18",
      "player_count": 16,
      "store_name": "Card Masters",
      "store_slug": "card-masters-austin",
      "city": "Austin",
      "state_region": "TX",
      "country": "US",
      "winner_name": "PlayerName",
      "winner_slug": "playername",
      "winning_deck": "Blue Flare",
      "winning_deck_slug": "blue-flare",
      "winning_deck_color": "Blue",
      "winning_deck_secondary_color": null
    }
  ],
  "pagination": { "page": 1, "per_page": 50, "total": 342, "total_pages": 7 },
  "stats": { ... },
  "monthly": [{ "month": "2026-04", "count": 48 }],
  "formats": [{ "format_id": "BT18", "set_name": "...", "display_name": "...", "release_date": "..." }],
  "event_types": [{ "event_type": "locals", "count": 210 }]
}

Response fields

FieldTypeDescription
tournament_idintUnique tournament identifier
event_datestringEvent date in YYYY-MM-DD format
event_typestringTournament tier: locals, regional, major, online
formatstringCard set format ID (e.g. BT18)
player_countintNumber of participants
store_namestringHost store display name
store_slugstringURL-safe store identifier for linking
citystring|nullStore city
state_regionstring|nullStore state or region code
countrystring|nullTwo-letter country code (ISO 3166-1)
winner_namestring|nullFirst-place player display name
winner_slugstring|nullWinner URL slug (for linking to profile)
winning_deckstring|nullWinning deck archetype name
winning_deck_slugstring|nullWinning deck URL slug
winning_deck_colorstring|nullPrimary color: Red, Blue, Yellow, Green, Black, Purple, White
winning_deck_secondary_colorstring|nullSecondary color (for dual-color decks), or null

stats, monthly, formats, and event_types are only included on page 1.

Error responses

StatusWhen
401 / 403Missing or invalid API key
429Rate limit exceeded

GET /api/decklists

Paginated decklist listings. Supports scene-aware listing mode or archetype-filtered mode.

Query parameters

ParamTypeDescription
pageintPage number. Default: 1
per_pageintResults per page. Default: 50, max: 100
archetype_idintFilter to a single archetype (activates archetype detail mode)
archetype_idsstringComma-separated archetype IDs for multi-select
archetypestringFilter by archetype slug (e.g. blue-flare)
formatstringFilter by format ID
event_typestringFilter by event type. Repeatable
placement_maxintMax placement (e.g. 8 for top 8 only)
colorsstringComma-separated color filters (e.g. Blue,Red)
scenestringFilter by scene slug
countrystringFilter by country code
searchstringSearch archetype or player names
date_fromstringStart date (YYYY-MM-DD)
date_tostringEnd date (YYYY-MM-DD)
sortstringSort field. Default: date. Values: date, placement, player_count, event_type, archetype, format
sort_dirstringSort direction. Default: desc

Response

{
  "data": [
    {
      "result_id": 5678,
      "tournament_id": 1234,
      "event_date": "2026-04-15",
      "event_type": "locals",
      "format": "BT18",
      "player_count": 16,
      "placement": 1,
      "wins": 4,
      "losses": 0,
      "ties": 0,
      "player_name": "PlayerName",
      "player_slug": "playername",
      "store_name": "Card Masters",
      "store_slug": "card-masters-austin",
      "archetype_name": "Blue Flare",
      "archetype_slug": "blue-flare",
      "primary_color": "Blue",
      "secondary_color": null,
      "display_card_id": "BT13-027"
    }
  ],
  "pagination": { "page": 1, "per_page": 50, "total": 156, "total_pages": 4 },
  "stats": { ... },
  "collage": [{ "card_id": "BT13-027" }],
  "formats": [...],
  "event_types": [...]
}

Response fields

FieldTypeDescription
result_idintUnique result identifier
tournament_idintAssociated tournament ID
event_datestringTournament date (YYYY-MM-DD)
event_typestringTournament tier
formatstringFormat ID
player_countintTournament size
placementintFinal standing (1 = winner)
winsintMatch wins
lossesintMatch losses
tiesintMatch ties/draws
player_namestringPlayer display name
player_slugstringPlayer URL slug
store_namestringHost store name
store_slugstringStore URL slug
archetype_namestringDeck archetype display name
archetype_slugstringDeck archetype URL slug
primary_colorstringDeck primary color
secondary_colorstring|nullDeck secondary color, or null
display_card_idstringRepresentative card ID for art display (e.g. BT13-027)

stats, collage, formats, and event_types are only included on page 1.

Error responses

StatusWhen
401 / 403Missing or invalid API key
429Rate limit exceeded

GET /api/stores

Paginated store directory with search and geographic filtering.

Query parameters

ParamTypeDescription
pageintPage number. Default: 1
per_pageintResults per page. Default: 50, max: 100
scenestringFilter by scene slug
countrystringFilter by country code
statestringFilter by state/region
continentstringFilter by continent
searchstringSearch store names and cities
min_tournamentsintMinimum tournament count. Default: 0
min_avg_turnoutintMinimum average player turnout. Default: 0
sortstringSort field. Default: tournaments. Values: name, tournaments, avg_turnout, players, recent
sort_dirstringSort direction. Default: desc

Response

{
  "data": [
    {
      "store_id": 42,
      "name": "Card Masters",
      "slug": "card-masters-austin",
      "city": "Austin",
      "state": "TX",
      "country": "US",
      "is_online": false,
      "scene_name": "Austin, TX",
      "scene_slug": "austin-tx",
      "tournament_count": 28,
      "unique_players": 67,
      "avg_turnout": 14,
      "most_recent": "2026-04-22",
      "latitude": 30.2672,
      "longitude": -97.7431
    }
  ],
  "pagination": { ... },
  "stats": { ... },
  "map_points": [{ "lat": 30.27, "lng": -97.74, "name": "Card Masters", "slug": "card-masters-austin", "city": "Austin", "country": "US", "is_online": false }]
}

Response fields

FieldTypeDescription
store_idintUnique store identifier
namestringStore display name
slugstringURL-safe identifier
citystring|nullCity name
statestring|nullState/region code
countrystring|nullTwo-letter country code
is_onlinebooltrue for online-only organizers
scene_namestring|nullAssociated scene display name
scene_slugstring|nullScene URL slug
tournament_countintTotal tournaments hosted
unique_playersintDistinct players who've attended
avg_turnoutintAverage players per event
most_recentstring|nullDate of most recent event (YYYY-MM-DD)
latitudefloat|nullStore latitude (for mapping)
longitudefloat|nullStore longitude (for mapping)

stats and map_points are only included on page 1.

Error responses

StatusWhen
401 / 403Missing or invalid API key
429Rate limit exceeded

GET /api/store/:id

Individual store data including location, scene, and summary stats.

Path parameters

ParamTypeDescription
:idintrequired Store ID

Response

{
  "store": {
    "id": 42,
    "name": "Card Masters",
    "slug": "card-masters-austin",
    "city": "Austin",
    "state": "TX",
    "country": "US",
    "scene_name": "Austin, TX",
    "scene_slug": "austin-tx",
    "total_tournaments": 28,
    "total_players": 67,
    "last_event": "2026-04-22",
    "top_deck": {
      "name": "Blue Flare",
      "primary_color": "Blue",
      "secondary_color": null
    }
  }
}

Response fields

FieldTypeDescription
idintStore ID
namestringStore display name
slugstringURL-safe identifier
citystring|nullCity
statestring|nullState/region code
countrystring|nullCountry code
scene_namestring|nullScene display name
scene_slugstring|nullScene URL slug
total_tournamentsintLifetime tournament count
total_playersintCumulative player-entries across all tournaments
last_eventstring|nullMost recent event date
top_deckobject|nullMost-played deck archetype at this store

Error responses

StatusWhen
404No store with the given ID exists

GET /api/scenes

All active scenes with geographic coordinates. Useful for building maps.

Response

[
  {
    "scene_id": 1,
    "name": "Austin, TX",
    "slug": "austin-tx",
    "display_name": "Austin, TX",
    "scene_type": "metro",
    "state_region": "TX",
    "country": "US",
    "continent": "North America",
    "lat": 30.2672,
    "lng": -97.7431
  }
]

Response fields

FieldTypeDescription
scene_idintUnique scene identifier
namestringScene name (used internally)
slugstringURL-safe identifier
display_namestringHuman-readable display name
scene_typestringGeographic level: metro, state, country, continent
state_regionstring|nullState/region code
countrystring|nullCountry code
continentstring|nullContinent name
latfloat|nullCenter latitude (avg of store locations)
lngfloat|nullCenter longitude

Returns a flat array (not paginated). Coordinates are the average of all store locations in the scene.

GET /api/scene/:slug

Scene overview with deck meta, recent tournaments, and top players for the current format.

Path parameters

ParamTypeDescription
:slugstringrequired Scene slug (e.g. austin-tx)

Response

{
  "scope": { "level": "scene", "label": "Austin, TX" },
  "decks": [
    {
      "archetype_name": "Blue Flare",
      "primary_color": "Blue",
      "secondary_color": null,
      "slug": "blue-flare",
      "display_card_id": "BT13-027",
      "entries": 42,
      "firsts": 8,
      "wins": 120,
      "losses": 48,
      "pilots": 18
    }
  ],
  "tournaments": [
    {
      "tournament_id": 1234,
      "event_date": "2026-04-15",
      "event_type": "locals",
      "format": "BT18",
      "player_count": 16,
      "store_name": "Card Masters",
      "winner_name": "PlayerName",
      "winning_deck": "Blue Flare",
      "winning_deck_color": "Blue",
      "winning_deck_secondary_color": null
    }
  ],
  "players": [
    {
      "id": 100,
      "name": "PlayerName",
      "slug": "playername",
      "rating": 1285,
      "events_played": 12,
      "wins": 8,
      "top3": 5,
      "top_deck": "Blue Flare",
      "deck_color": "Blue",
      "deck_secondary_color": null
    }
  ]
}

Response fields

FieldTypeDescription
scope.levelstringData granularity: scene, state, country, or continent (cascades up if insufficient data)
scope.labelstringDisplay label for the scope level
decks[].entriesintTotal entries (results) for this archetype in this scope
decks[].firstsintNumber of first-place finishes
decks[].winsintTotal match wins
decks[].lossesintTotal match losses
decks[].pilotsintDistinct players who've played this deck
players[].ratingintCompetitive rating score
players[].top3intNumber of top-3 finishes

If the scene has fewer than 5 data points, data cascades up to state, country, or continent level. The scope field indicates the actual level returned.

Error responses

StatusWhen
404No scene with the given slug exists

GET /api/scene/:slug/tournaments

Tournament listing for a specific scene.

Path parameters

ParamTypeDescription
:slugstringrequired Scene slug

Response

{
  "scope": { "level": "scene", "label": "Austin, TX" },
  "tournaments": [
    {
      "tournament_id": 1234,
      "event_date": "2026-04-15",
      "event_type": "locals",
      "format": "BT18",
      "player_count": 16,
      "store_name": "Card Masters",
      "winner_name": "PlayerName",
      "winning_deck": "Blue Flare",
      "winning_deck_color": "Blue",
      "winning_deck_secondary_color": null
    }
  ]
}

Tournament fields are the same as the tournaments endpoint. Scope cascades apply.

Error responses

StatusWhen
404No scene with the given slug exists

GET /api/deck/:id

Deck archetype information with colors, stats, and display card.

Path parameters

ParamTypeDescription
:idintrequired Archetype ID

Response

{
  "deck": {
    "id": 15,
    "name": "Blue Flare",
    "slug": "blue-flare",
    "primary_color": "Blue",
    "secondary_color": null,
    "display_card_id": "BT13-027",
    "total_entries": 342,
    "firsts": 64,
    "pilots": 128,
    "meta_pct": 12.4,
    "top3_count": 95,
    "top3_rate": 27.8
  }
}

Response fields

FieldTypeDescription
idintArchetype ID
namestringArchetype display name
slugstringURL-safe identifier
primary_colorstringPrimary deck color
secondary_colorstring|nullSecondary color for dual-color decks
display_card_idstringRepresentative card ID
total_entriesintTotal tournament results with this archetype
firstsintFirst-place finishes
pilotsintDistinct players who've played this deck
meta_pctfloatMetagame share percentage (current format)
top3_countintTop-3 finishes
top3_ratefloatTop-3 rate as percentage of entries

Error responses

StatusWhen
404No archetype with the given ID exists

GET /api/cards

Card search with filtering by set, color, type, and text.

Query parameters

ParamTypeDescription
qstringSearch by card name or card ID (e.g. BT13-027)
colorstringFilter by color: Red, Blue, Yellow, Green, Black, Purple, White
card_typestringFilter by type: Digimon, Tamer, Option, Digi-Egg
set_codestringFilter by set code (e.g. BT13)
level_minintMinimum level (Digimon only)
level_maxintMaximum level
cost_minintMinimum play cost
cost_maxintMaximum play cost
pageintPage number. Default: 1
per_pageintResults per page. Default: 50

Response

{
  "data": [
    {
      "card_id": "BT13-027",
      "name": "MailBirdramon",
      "display_name": null,
      "card_type": "Digimon",
      "color": "Blue",
      "color2": null,
      "level": 4,
      "dp": 5000,
      "play_cost": 5,
      "digi_type": "Bird",
      "attribute": "Vaccine",
      "stage": "Champion",
      "rarity": "C",
      "set_code": "BT13"
    }
  ],
  "pagination": { "page": 1, "per_page": 50, "total": 1, "total_pages": 1 }
}

Response fields

FieldTypeDescription
card_idstringUnique card identifier (e.g. BT13-027)
namestringCard name
display_namestring|nullAlternate display name, if different from name
card_typestringDigimon, Tamer, Option, or Digi-Egg
colorstringPrimary card color
color2string|nullSecondary color (dual-color cards)
levelint|nullDigimon level (null for non-Digimon)
dpint|nullDigimon Power (null for non-Digimon)
play_costint|nullMemory cost to play
digi_typestring|nullDigimon type (e.g. Dragon, Bird)
attributestring|nullDigimon attribute: Vaccine, Virus, Data, Free
stagestring|nullEvolution stage: In-Training, Rookie, Champion, Ultimate, Mega
raritystringCard rarity: C, U, R, SR, SEC
set_codestringSet code (e.g. BT13, EX05)

Error responses

StatusWhen
401 / 403Missing or invalid API key
429Rate limit exceeded

API Stability

The DigiLab API is unversioned. Here's what that means for you:

  • We may add new fields to responses at any time. Your code should ignore unknown fields gracefully.
  • We may add new endpoints without notice.
  • We will not remove or rename existing fields without advance notice on Discord and in the changelog below.
  • We will not change the meaning of existing fields.
  • Breaking changes (removed fields, changed types, removed endpoints) will be announced at least 30 days in advance.
Tip:

Parse responses with a lenient JSON parser and avoid strict schema validation. New fields appearing in responses is expected and not a breaking change.

Terms of Use

By using the DigiLab API, you agree to the following:

Permitted use

  • Building community tools, Discord bots, websites, and apps for the Digimon TCG community
  • Academic research and data analysis
  • Personal projects and learning

Not permitted

  • Commercial resale of raw API data
  • Bulk scraping beyond normal API usage patterns
  • Misrepresentation — do not present DigiLab data as your own without attribution
  • Abuse — do not use the API to harass, spam, or harm community members

Attribution

If you display DigiLab data publicly, please include a visible link back to digilab.cards. Example:

Data provided by DigiLab (digilab.cards)

Key revocation

API keys may be revoked without notice for violation of these terms, sustained abuse, or excessive load. If your key is revoked, contact us on Discord to discuss.

Changelog

DateChange
2026-05-01Public API launch with 10 endpoints, API key authentication, and rate limiting. Documentation published at api.digilab.cards.

Subscribe to the #api channel on Discord for update notifications.