Search & filtering

The q parameter is a compact query language for finding cards and expansions — match on any field, combine conditions with AND/OR, exclude with a minus, use wildcards and numeric ranges. It’s accepted by Search cards, Search expansions, and List cards in an expansion.

The basics

A query is a set of field:value terms. A bare word with no field is matched against name. Matching is case-insensitive, and text fields match on substringsname:char finds “Charizard” and “Charmander”.

charizard                 → name contains "charizard"
name:charizard            → same, explicit
supertype:Trainer         → all Trainer cards
rarity:"Special Illustration Rare"   → quote values that contain spaces

Wrap a value in double quotes when it contains spaces. Use ! before a field for an exact (whole-value) match instead of a substring:

!name:pikachu             → name is exactly "Pikachu" (not "Pikachu V")

Combining terms

Multiple terms are ANDed together. Use OR (uppercase) and parentheses to group alternatives, and a leading - to exclude.

name:charizard subtypes:vmax            → charizard AND a VMAX
(subtypes:mega OR subtypes:vmax)        → either subtype
name:char* -types:water                 → char… but NOT Water type
supertype:Pokémon -rarity:Common        → Pokémon that aren't Common

Wildcards

* matches any run of characters. Put it anywhere except the start of a value.

name:char*                → starts with "char"
name:char*der             → starts "char", ends "der" (Charmander)
  • Leading wildcards (*zard) are not allowed — plain text search already matches substrings, so use name:zard.
  • At most 3 * per value, and at least 2 literal characters.

Numeric & date ranges

Range syntax works on number and date fields. Square brackets are inclusive, curly braces are exclusive, and * is an open (unbounded) end.

hp:[150 TO *]                  → hp ≥ 150
hp:{150 TO 200}                → 150 < hp < 200  (exclusive)
raw_price:[100 TO 500]         → $100–$500 inclusive
expansion.release_date:[2024-01-01 TO *]   → released on/after 2024-01-01
card_count.total:[200 TO *]    → big sets (expansions search)

A plain value on a number field is an equality test: hp:150 means exactly 150.

Nested & list fields

Some fields are lists or nested objects. You query them with a dotted name; the term matches if any element matches.

subtypes:mega                  → one of the card's subtypes is "mega"
attacks.name:"G-Max Wildfire"  → has an attack with that name
abilities.text:draw            → an ability whose text mentions "draw"
expansion.id:sv1               → only cards in set sv1
weaknesses.type:Water          → weak to Water

Searchable fields — cards

FieldTypeNotes
nametextDefault field — a bare term matches on name
idexact idFull card id, e.g. sv3pt5-6
supertypetexte.g. Pokémon, Trainer, Energy
subtypesarrayMatches any one subtype, e.g. VMAX, Mega
typesarrayPokémon energy types (One Piece: colors)
hpnumberSupports ranges
numberexact idPrinted number; ranges match the numeric part
raritytexte.g. Rare Holo, Special Illustration Rare
artisttextIllustrator name (alias: illustrator)
raw_pricenumberUngraded market price (USD); supports ranges
is_variant / is_holo / is_reverse / is_first_editionbooleantrue or false
abilities.name / abilities.texttextSearches within the card’s abilities
attacks.name / attacks.texttextSearches within the card’s attacks
attacks.damagenumberNumeric attack damage; supports ranges
weaknesses.type / resistances.typetexte.g. Water, Fire
expansion.idexact idRestrict to one set, e.g. sv3pt5
expansion.nametextSet name
expansion.series_idexact idSeries id, e.g. sv
expansion.release_datedateSet release date; supports ranges
languageexact ide.g. en, ja, zh

One Piece cards reuse these fields — types holds the card’s colors and hp its power. Fields not listed here (e.g. national_pokedex_numbers) are not searchable and return a 400.

Searchable fields — expansions

FieldTypeNotes
nametextDefault field
idexact idExpansion id, e.g. sv3pt5
series_idexact idSeries id, e.g. sv
languageexact ide.g. en, ja, zh
release_datedateSupports ranges
card_count.totalnumberTotal cards incl. secret rares; supports ranges
card_count.officialnumberPrinted count; supports ranges

Sorting — orderBy

A comma-separated list of fields; prefix a field with - for descending. Up to 3 keys. Results always get a stable tiebreak on id.

orderBy=-release_date          → newest sets first
orderBy=-raw_price,name        → most expensive first, then A→Z

Sortable card fields: name, hp, number, rarity, raw_price, expansion.release_date, id. Sortable expansion fields: name, release_date, id.

Paging & trimming the response

  • page (default 1) and page_size (default 100, max 100). page × page_size can’t exceed 10,000 — narrow with q to go deeper.
  • Every list response includes total_count so you can compute the last page.
  • select=id,name,rarity returns only those top-level fields (id is always included).
  • include=prices adds raw + graded pricing under each card’s variants[].prices.

Limits & errors

A malformed query returns 400 with error: "invalid_query". When the problem is at a specific spot, details.position is the 0-based character offset, and an unknown field comes back with a suggestion.

GET /api/v1/pokemon/cards?q=subtype:mega

400 {
  "success": false,
  "message": "unknown field \"subtype\". Did you mean \"subtypes\"?",
  "error": "unknown_field",
  "details": { "position": 0 }
}
  • Max query length 512 characters.
  • Max 20 terms and parenthesis nesting up to 5 deep.
  • Unknown fields, leading wildcards, and unquoted spaces are rejected rather than ignored.

Worked examples

# Charizard VMAX/Mega cards with at least 300 HP, priciest first, with prices
GET /api/v1/pokemon/cards?q=name:charizard (subtypes:vmax OR subtypes:mega) hp:[300 TO *]&orderBy=-raw_price&include=prices

# Non-Common Water Pokémon in Scarlet & Violet era sets
GET /api/v1/pokemon/cards?q=types:Water -rarity:Common expansion.series_id:sv

# One Piece Leaders that are red, sorted by name
GET /api/v1/onepiece/cards?q=supertype:Leader types:Red&orderBy=name

# English sets from 2024 onward with 200+ cards, newest first
GET /api/v1/pokemon/expansions?q=language:en release_date:[2024-01-01 TO *] card_count.total:[200 TO *]&orderBy=-release_date

Every endpoint page has a live “Try it” runner with a q box — edit any example above and run it against staging.