TCGdex Dart SDK

A Dart/Flutter SDK for the TCGdex API β€” the open-source PokΓ©mon TCG database.

Dart License: MIT

Features

  • πŸƒ Full card data β€” search, filter, and get detailed card information
  • πŸ“¦ All 17 endpoints β€” cards, sets, series, types, rarities, illustrators, and more
  • πŸ” Powerful query builder β€” filter, sort, and paginate with a fluent API
  • πŸ’Ύ Built-in caching β€” in-memory cache with configurable TTL
  • 🧊 Immutable models β€” type-safe models powered by Freezed
  • 🌍 Multi-language β€” supports all languages available in the TCGdex API

Installation

Add the SDK to your pubspec.yaml:

dependencies:
  tcgdex_sdk:
    git:
      url: https://github.com/verxos/tcgdex-dart-sdk.git

Then run:

dart pub get
# or for Flutter
flutter pub get

Quick Start

import 'package:tcgdex_sdk/tcgdex_sdk.dart';

void main() async {
  final tcgdex = TCGdex();

  // Search for cards
  final cards = await tcgdex.cards.list(
    query: TCGdexQuery.create().like('name', 'Pikachu'),
  );
  print('Found ${cards.length} Pikachu cards');

  // Get a specific card
  final card = await tcgdex.cards.get('swsh3-136');
  print('${card?.name} β€” HP: ${card?.hp}');
}

Usage

Initializing the Client

// Default (English, standard endpoint)
final tcgdex = TCGdex();

// Custom language
final tcgdex = TCGdex(lang: 'fr');

// Custom cache TTL
final tcgdex = TCGdex(defaultTtl: Duration(minutes: 30));

Available Endpoints

Endpoint Type List returns Get returns
tcgdex.cards Full detail List<CardResume> CardDetail
tcgdex.sets Full detail List<SetResume> SetDetail
tcgdex.series Full detail List<SerieResume> SerieDetail
tcgdex.types String list List<String> StringEndpoint
tcgdex.rarities String list List<String> StringEndpoint
tcgdex.categories String list List<String> StringEndpoint
tcgdex.illustrators String list List<String> StringEndpoint
tcgdex.stages String list List<String> StringEndpoint
tcgdex.suffixes String list List<String> StringEndpoint
tcgdex.trainerTypes String list List<String> StringEndpoint
tcgdex.energyTypes String list List<String> StringEndpoint
tcgdex.regulationMarks String list List<String> StringEndpoint
tcgdex.variants String list List<String> StringEndpoint
tcgdex.hp Numeric list List<int> StringEndpoint
tcgdex.retreats Numeric list List<int> StringEndpoint
tcgdex.dexIds Numeric list List<int> StringEndpoint

Plus: tcgdex.getRandomCard() β†’ Future<CardDetail?>

Searching with Queries

final query = TCGdexQuery.create()
    .contains('name', 'Gardevoir')      // name contains "Gardevoir"
    .contains('legal.standard', 'true') // legal in Standard format
    .sort('hp', ascending: false)       // sort by HP descending
    .paginate(1, 20);                   // page 1, 20 items per page

final results = await tcgdex.cards.list(query: query);

All query methods:

Method Example API filter
.contains(key, value) .contains('name', 'pika') Substring match
.equal(key, value) .equal('hp', '100') eq:100
.notEqual(key, value) .notEqual('rarity', 'Common') neq:Common
.notContains(key, value) .notContains('name', 'EX') not:EX
.like(key, value) .like('name', 'gar*') Alias for contains
.isNull(key) .isNull('image') null:
.isNotNull(key) .isNotNull('image') notnull:
.greaterOrEqualThan(key, n) .greaterOrEqualThan('hp', 100) gte:100
.lesserOrEqualThan(key, n) .lesserOrEqualThan('hp', 50) lte:50
.sort(key, ascending:) .sort('name') Sort results
.paginate(page, perPage) .paginate(1, 20) Pagination

Working with Card Data

final card = await tcgdex.cards.get('swsh3-136');

if (card != null) {
  print(card.name);           // "Furret"
  print(card.hp);             // 110
  print(card.stage);          // "Stage1"
  print(card.legal.standard); // false
  print(card.legal.expanded); // true

  // Get image URL
  final imageUrl = card.getImageUrl(quality: 'high', extension: 'png');
  // β†’ https://assets.tcgdex.net/en/swsh/swsh3/136/high.png

  // Attacks
  for (final attack in card.attacks ?? []) {
    print('${attack.name} β€” ${attack.damage} damage');
  }
}

Using Sets and Series

// List all sets
final allSets = await tcgdex.sets.list();

// Get a specific set with its cards
final set = await tcgdex.sets.get('swsh3');
print('${set?.name} β€” ${set?.cardCount.total} cards');

// List all series
final allSeries = await tcgdex.series.list();
final serie = await tcgdex.series.get('swsh');
print('${serie?.name} β€” ${serie?.sets.length} sets');

Using String/Numeric Endpoints

// List all available types
final types = await tcgdex.types.list();
// β†’ ["Colorless", "Darkness", "Dragon", "Fairy", "Fighting", ...]

// Get all cards of a specific type
final fireCards = await tcgdex.types.get('Fire');
print('${fireCards?.cards.length} Fire cards');

// List all HP values
final hpValues = await tcgdex.hp.list();
// β†’ [10, 30, 40, 50, 60, ...]

// Get cards with 300 HP
final hp300 = await tcgdex.hp.get(300);
print('${hp300?.cards.length} cards with 300 HP');

Random Card

final randomCard = await tcgdex.getRandomCard();
print('Random card: ${randomCard?.name}');

Flutter Integration Example

import 'package:flutter/material.dart';
import 'package:tcgdex_sdk/tcgdex_sdk.dart';

class PokemonCardSearch extends StatefulWidget {
  @override
  State<PokemonCardSearch> createState() => _PokemonCardSearchState();
}

class _PokemonCardSearchState extends State<PokemonCardSearch> {
  final tcgdex = TCGdex();
  List<CardResume> cards = [];
  bool loading = false;

  Future<void> search(String name) async {
    setState(() => loading = true);
    final query = TCGdexQuery.create().like('name', '$name*');
    final results = await tcgdex.cards.list(query: query);
    setState(() {
      cards = results;
      loading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          onSubmitted: search,
          decoration: InputDecoration(
            hintText: 'Search for a PokΓ©mon card...',
            prefixIcon: Icon(Icons.search),
          ),
        ),
        if (loading) CircularProgressIndicator(),
        Expanded(
          child: ListView.builder(
            itemCount: cards.length,
            itemBuilder: (context, index) {
              final card = cards[index];
              return ListTile(
                leading: card.image != null
                    ? Image.network(
                        card.getImageUrl(quality: 'low')!,
                        width: 40,
                      )
                    : null,
                title: Text(card.name),
                subtitle: Text(card.id),
              );
            },
          ),
        ),
      ],
    );
  }
}

Models

All models are immutable and support copyWith, toJson, and fromJson:

// Create from JSON
final card = CardResume.fromJson({'id': 'xy1-1', 'localId': '1', 'name': 'Venusaur'});

// Serialize to JSON
final json = card.toJson();

// Copy with modifications
final copy = card.copyWith(name: 'Modified Name');

API Reference

License

MIT License β€” see LICENSE for details.

Libraries

tcgdex_sdk
Support for doing something awesome.