API

The card catalogue as JSON. Read-only, with a key.

Key

Ask for access on Discord. Your key then appears under Account on My Decks.

Send it in a header on every request. The base URL is https://fowca.gg.

curl -H "Authorization: Bearer fowca_YOUR_KEY" \
  "https://fowca.gg/api/cards/search?q=set%3ACPB&limit=200"

# or
curl -H "X-API-Key: fowca_YOUR_KEY" "https://fowca.gg/api/card/CPB-017"

Check that it works with GET /api/key. It answers { ok, user, limit, remaining, reset } for a valid key and 401 without one.

Limits and errors

600 requests per 15 minutes per key. Without a key you get a small allowance for trying things out. Every response has RateLimit and RateLimit-Policy headers. Responses carry an ETag, so If-None-Match returns 304 when nothing changed.

Errors are JSON: { "error": "..." }.

StatusMeaning
400A bad parameter, a key sent in the URL, or a query over 500 characters or 40 terms.
401Malformed API key, or Invalid or revoked API key.
403API keys are read-only, or Price data is not available through the API.
404Card not found, or Not found for an unknown path.
429Over the limit. Retry-After says how many seconds to wait.

GET /api/cards/search

One row per card. q uses the search syntax. With no q it returns the whole catalogue.

ParameterMeaning
qSearch query, such as set:CPB or artist:"Kairi Miura".
pagePage number, from 1.
limitRows per page, 1 to 200. Default 60.
offsetRow offset. Overrides page.
sortname, cost, atk, def, released, set, type, color, rarity, popularity.
dirasc or desc.
uniqueprints returns every printing, variants included.
formatOnly cards legal in that format, such as paradox or evil_cluster. Same as format: in q.
nameExact card name. Returns every match and ignores the other parameters.
{
  "cards": [
    {
      "code": "TTW-002",
      "name": "Alice's Little Supply Force",
      "type": "Resonator",
      "cost": "{W}",
      "atk": "200",
      "def": "200",
      "rarity": "C",
      "variant_type": null,
      "race": "Soldier",
      "attribute": "{W}",
      "set_code": "TTW",
      "release_date": "2015-12-11",
      "is_main_set": true,
      "illustrator": "城戸春一",
      "artists": ["城戸春一"],
      "illustrator_canonical": "Haruichi Kido",
      "hasBack": false,
      "hasBack2": false
    }
  ],
  "total": 111,
  "page": 1,
  "totalPages": 2,
  "offset": 0,
  "description": "where in set \"TTW\"",
  "warnings": [],
  "sort": "name",
  "dir": "asc"
}
FieldMeaning
codeThe printing, and the id for the card endpoint. Case-sensitive.
nameCard name. Not unique. Split cards join both halves with //.
cost, attributeSymbols, such as {W}{W}{1}.
atk, defNumbers sent as strings, or null.
rarityC, U, R, SR, MR and so on.
variant_typenull for a regular print, else the variant, such as Full Art.
set_code, release_dateThe set, and its date as YYYY-MM-DD.
is_main_setfalse for promos and starter decks.
artistsWho drew it, one name each. Some cards have several.
illustratorThe same names on one line, joined with / .
illustrator_canonicalThat line with each artist under one spelling.
hasBack, backFace1Two-sided cards. backFace1 has the other side's code, name and type.
warningsParts of the query that were not understood.

Card

GET /api/card/:code

One printing in full. Add ?variant=Full+Art for a variant of the same code.

FieldMeaning
code, name, dbNamedbName is the exact name the name= parameters take.
type, subtype, race, attributeThe type line.
cost, totalCost, atk, deftotalCost is a number. The rest are strings.
divinity, willpowerStrings, on the card types that have them.
text, flavor_text, solo_textRules text, one ability per line.
artists, illustrator, illustrator_canonicalAs in search.
setName, rarity, release_date, variant_typeThis printing.
printingsEvery printing: [{ code, set_name, rarity, variant_type, tcgplayer_id }].
legalityLegal, Not Legal, Banned or Restricted per format.
facesThe other sides of a two-sided card.
rulings, references, referencedByOfficial rulings, and cards that name each other.
usageUp to 20 tournament decklists that play it.

Fields not listed here may change.

Sets

GET /api/sets

Every set, newest first. Use code in set:CODE searches.

[
  { "code": "QSK", "name": "The Quest of the Seven Keys", "release_date": "2026-09-25", "card_count": 109 }
]

More endpoints

EndpointReturns
GET /api/cards/printings?name=All printings of one card: [{ code, set_name, rarity, variant_type, tcgplayer_id }].
GET /api/cards/filters{ types, sets, rarities, attributes }. sets holds names. For codes use /api/sets.
GET /api/cards/suggest?q=Up to 8 name matches for 2 or more letters: [{ type, text, code }].
GET /api/cards/top?era=&region=The 30 most-played cards: [{ name, code, deck_count, total_copies }].
GET /api/cards/random?count=1 to 20 random cards: [{ code, name }].
GET /api/erasThe clusters, whose id is the era value above.

Images

Thumbnails are at https://fowca.gg/img/thumb/CODE.webp?w=260. w is 130, 260, 390, 520 or 744. No key needed.

Keeping a copy

The whole catalogue is about 30 requests. New printings are easiest to find by date.

# every card, 200 at a time, until page passes totalPages
GET /api/cards/search?limit=200&page=1

# every printing, newest first; stop at one you already have
GET /api/cards/search?unique=prints&sort=released&dir=desc&limit=200

# or compare the set list, then fetch the sets you lack
GET /api/sets
GET /api/cards/search?q=set%3ACPB&limit=200

Use