📚 Documentation

PokéWallet API
Documentation

Complete REST reference for the most comprehensive Pokémon TCG platform. Real-time pricing, 50,000+ cards database, and generous rate limits.

👨‍🍳Still cooking – Taste it while it's hot!
50,000+ CardsComplete TCG Database
Real-Time PricingTCGPlayer & CardMarket
Fast & ReliableGlobal CDN, <100ms latency
Base URL:https://api.pokewallet.io

Quick Start

Get started with PokéWallet API in 4 simple steps:

1

Create an Account

Sign up for free to start using the API. Upgrade anytime from your dashboard.

Sign Up Now
2

Generate an API Key

Create your first API key from the dashboard.

3

Make Your First Request

Start querying the API with your key.

cURL
curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/search?q=charizard"
4

Join the Discord Community

Stay up to date with new features, ask for help, and connect with other developers.

Join Discord

Authentication

All API requests (except /health) require authentication using an API key.

API Key Format

API keys follow this format:

  • Production keys: pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Development keys: pk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Security Warning: Never expose your API keys in client-side code, public repositories, or logs. Always use environment variables.

Authentication Methods

You can authenticate using either the X-API-Key header or Authorization header:

X-API-Key Header (Recommended)
curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/search?q=pikachu"
Authorization Header
curl -H "Authorization: Bearer pk_live_your_key_here" \
     "https://api.pokewallet.io/search?q=pikachu"

Rate Limits

Rate limits vary depending on your subscription plan:

PlanHourly LimitDaily LimitPrice
Free100 requests1,000 requests$0/month
Early Access ⭐1,000 requests10,000 requestsNo longer available
Coffee ☕1,000+ requests10,000+ requestsBuy a coffee on Ko-fi
Pro5,000 requests50,000 requests€20/month
BusinessCustomCustomContact us
All new users start on the Free plan. Upgrade from your dashboard.
Early Access was our initial launch tier and is no longer available for new users.
Please note: After upgrading your plan, activation may require a couple of hours.

Rate Limit Headers

Every API response includes rate limit information:

X-RateLimit-Limit-Hour: 100
X-RateLimit-Remaining-Hour: 95
X-RateLimit-Limit-Day: 1000
X-RateLimit-Remaining-Day: 823

Rate Limit Exceeded (429)

When you exceed your rate limit, you'll receive a 429 Too Many Requests response:

{
  "error": "Rate limit exceeded",
  "message": "Hourly limit exceeded",
  "limits": {
    "hourly": {
      "limit": 100,
      "used": 100,
      "remaining": 0
    },
    "daily": {
      "limit": 1000,
      "used": 523,
      "remaining": 477
    }
  }
}

Card ID Formats

The API uses two different ID formats depending on the card's data source:

TCG Cards (TCGPlayer)

pk_ + hash

Format: pk_ + hexadecimal hash

Example:

pk_72046138a4c1908a9f27c93fdd8189ba...

Usage: All cards with TCGPlayer data (even if they also have CardMarket data)

CardMarket-Only Cards

No prefix

Format: Direct hexadecimal hash (no pk_ prefix)

Example:

2208e8a2750c07d89e54870ffcef80d1...

Usage: Only cards exclusively from CardMarket (e.g., Japanese sets, European promos)

Unique Variants: Cards with the same card_number but different variants (V1, V2, etc.) have unique IDs.

Price Variants

Prices come from two different sources, each with its own way of classifying card variants. Understanding this distinction is important when reading the prices array in any response.

TCGPlayer

🇺🇸 USA
sub_type_name

Uses a sub_type_name field to distinguish versions:

NormalCommon / non-holo cards
HolofoilHolo cards
Reverse HolofoilMost Vintage Sets (Base through Neo)
1st EditionBase Set 1st Ed and similar
UnlimitedStandard version of sets that have 1st editions
ShadowlessSpecific Base Set variants

CardMarket

🇪🇺 Europe
variant_type

Uses a simpler variant_type field:

normalStandard non-holo version
holoHolo version
CardMarket uses a simpler two-tier system regardless of the set era.

Public Endpoints

No Authentication Required: These endpoints are publicly accessible.
GET/healthNo Auth Required

Check API status, database, cache, and storage health with response times.

Example Request:

cURL
curl "https://api.pokewallet.io/health"

Response Example (Healthy):

200 OK
{
  "status": "healthy",
  "timestamp": "2025-12-16T10:30:00.000Z",
  "version": "1.1.0",
  "checks": {
    "database": {
      "status": "healthy",
      "responseTime": 45
    },
    "cache": {
      "status": "healthy",
      "responseTime": 3
    },
    "storage": {
      "status": "healthy",
      "responseTime": 12
    }
  },
  "responseTime": 60,
  "region": "FRA"
}

Response Example (Unhealthy):

503 Service Unavailable
{
  "status": "unhealthy",
  "timestamp": "2025-12-16T10:30:00.000Z",
  "version": "1.1.0",
  "message": "Critical services unavailable - API may not function correctly",
  "checks": {
    "database": {
      "status": "unhealthy",
      "responseTime": null,
      "message": "Connection failed"
    },
    "cache": {
      "status": "healthy",
      "responseTime": 3
    },
    "storage": {
      "status": "healthy",
      "responseTime": 12
    }
  },
  "responseTime": 1050,
  "region": "FRA"
}
GET/No Auth Required

Get API information, version, and available endpoints.

Example Request:

cURL
curl "https://api.pokewallet.io/"

Response Example:

200 OK
{
  "name": "PokeWallet API",
  "version": "1.1.0",
  "status": "production",
  "authentication": {
    "required": true,
    "method": "API Key",
    "header": "X-API-Key",
    "format": "pk_live_xxxxxxxxxxxxx"
  },
  "endpoints": {
    "health": { "path": "/health", "auth_required": false },
    "search": { "path": "/search?q=charizard&limit=20", "auth_required": true },
    "cardDetail": { "path": "/cards/:id", "auth_required": true },
    "sets": { "path": "/sets", "auth_required": true },
    "setDetails": { "path": "/sets/:setCode?page=1&limit=50", "auth_required": true },
    "images": { "path": "/images/:id?size=high", "auth_required": true }
  },
  "rate_limits": {
    "per_hour": 100,
    "per_day": 1000,
    "plan": "free"
  }
}

Search Endpoints

Authentication Required: All Search endpoints require an API key.
GET/search/by-price-rangeComing Soon

Search cards by price range with optional filters for rarity and set.

⏳ This endpoint is currently in development and will be available soon after thorough testing.

GET/search/by-typeComing Soon

Search cards by card type (Pokemon, Trainer, Energy) and optional subtype filters.

⏳ This endpoint is currently in development and will be available soon after thorough testing.

Cards Endpoints

Authentication Required: All Cards endpoints require an API key in the X-API-Key header.
GET/cards/:id

Get complete card details with unified pricing from TCGPlayer and CardMarket.

Parameters:

ParameterTypeRequiredDescription
idstringRequiredCard ID - Two formats supported:
  • TCG cards: pk_xxx (with prefix)
  • CardMarket-only: hexadecimal hash (no prefix)
set_codestringOptionalSet code for disambiguation (e.g., "SWSH3", "SV1", "CBB3C"). Supports both alphanumeric codes and numeric group IDs.

Example Request:

cURL
curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/cards/pk_xxx"

Response Example:

200 OK
{
  "id": "pk_xxx",
  "card_info": {
    "name": "Charizard VMAX",
    "clean_name": "Charizard VMAX",
    "set_name": "Darkness Ablaze",
    "set_code": "SWSH3",
    "set_id": "22789",
    "card_number": "20/189",
    "rarity": "Secret Rare",
    "card_type": "Pokemon",
    "hp": "330",
    "stage": null,
    "card_text": "VMAX rule: When your VMAX Pokemon is Knocked Out...",
    "attacks": ["Fire Spin - 320 damage"],
    "weakness": "Water",
    "resistance": null,
    "retreat_cost": "3"
  },
  "tcgplayer": {
    "url": "https://tcgplayer.com/product/123456",
    "prices": [
      {
        "sub_type_name": "Normal",
        "low_price": 245.99,
        "mid_price": 299.99,
        "high_price": 450.00,
        "market_price": 285.00,
        "direct_low_price": 250.00,
        "updated_at": "2025-12-16T04:00:00Z"
      }
    ]
  },
  "cardmarket": {
    "product_name": "Charizard VMAX (Secret)",
    "product_url": "https://cardmarket.com/product/789012",
    "prices": [{
      "variant_type": "normal",
      "avg": 260.50,
      "low": 240.00,
      "trend": 270.00,
      "avg1": 258.30,
      "avg7": 255.80,
      "avg30": 280.50,
      "updated_at": "2025-12-16T04:00:00Z"
    }]
  }
}
GET/cards/:id/price-historyComing Soon

Get CardMarket price history with 1, 7, and 30-day averages and percentage changes for all card variants.

⏳ This endpoint is currently in development and will be available soon after thorough testing.

GET/cards/:id/price-comparisonComing Soon

Compare prices between TCGPlayer and CardMarket with best deal analysis and recommendations.

⏳ This endpoint is currently in development and will be available soon after thorough testing.

GET/cards/:id/variantsComing Soon

Get all available variants of a card (normal, holo, reverse holo, etc.) with prices and availability from both markets.

⏳ This endpoint is currently in development and will be available soon after thorough testing.

Sets Endpoints

Authentication Required: All Sets endpoints require an API key.
GET/sets

Get list of all Pokemon sets with card counts.

Response Fields:

FieldTypeDescription
namestringSet name
set_codestring | nullShort code for the set (e.g., "SV1", "SWSH3"). May be null for some promo or special sets.
set_idstringUnique numeric identifier for the set (group_id)
card_countnumberTotal number of unique cards in the set
languagestring | nullSet language code (e.g., "eng", "jap", "ger"). May be null if not specified.
release_datestring | nullSet release date (e.g., "3rd August, 2007"). May be null if unknown.

Example Request:

curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/sets"

Response Example:

200 OK
{
  "success": true,
  "data": [
    {
      "name": "Scarlet & Violet",
      "set_code": "SV1",
      "set_id": "23456",
      "card_count": 198,
      "language": "eng",
      "release_date": "31st March, 2023"
    },
    {
      "name": "Silver Tempest",
      "set_code": "SWSH12",
      "set_id": "23123",
      "card_count": 245,
      "language": "eng",
      "release_date": "11th November, 2022"
    },
    {
      "name": "Vaporeon VMAX Promo",
      "set_code": null,
      "set_id": "24073",
      "card_count": 1,
      "language": "jap",
      "release_date": null
    }
  ],
  "total": 150
}
GET/sets/:setCode

Get set details with paginated card list.

Parameters:

ParameterTypeRequiredDescription
setCodestringRequiredSet identifier - accepts either set_code (e.g., "SWSH3", "SV1") or set_id (e.g., "23456"). Both values are returned by the /sets endpoint.
pagenumberOptionalPage number (default: 1)
limitnumberOptionalResults per page (default: 50, max: 200)
languagestringOptionalFilter by language when a set_code matches multiple sets (e.g., eng, jap, chn). Not needed when using a numeric set_id.

Set Object Fields:

FieldTypeDescription
namestringSet name
set_codestring | nullShort code for the set. May be null for some promo sets.
set_idstringUnique numeric identifier for the set (group_id)
total_cardsnumberTotal number of unique cards in the set
languagestring | nullSet language code (e.g., "eng", "jap"). May be null if not specified.
release_datestring | nullSet release date (e.g., "3rd August, 2007"). May be null if unknown.

Example Request:

curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/sets/SWSH3"

Response Example:

200 OK
{
  "success": true,
    "set": {
        "name": "Plasma Freeze",
        "set_code": "PLF",
        "set_id": "1382",
        "total_cards": 123,
        "language": "eng",
        "release_date": "8th May, 2013"
    },
    "cards": [
        {
            "id": "pk_4687f4c4a0499fd6a7fa267a9bef2cb4c462f19478522c5a85eaf116ca1d1f0c8ad2ba5fc8ac3c668627bce5",
            "card_info": {
                "name": "Weedle",
                "clean_name": "Weedle",
                "set_name": "Plasma Freeze",
                "set_code": "1382",
                "card_number": "1/116",
                "rarity": "Common",
                "card_type": null,
                "hp": "50.0",
                "stage": "Basic",
                "card_text": null,
                "attacks": [
                    "[G] Triple Stab (10x) Flip 3 coins.  This attack does 10 damage times the number of heads."
                ],
                "weakness": "Rx2",
                "resistance": null,
                "retreat_cost": "1.0"
            },
            "tcgplayer": {
                "prices": [],
                "url": "https://www.tcgplayer.com/product/90547"
            },
            "cardmarket": {
                "product_name": "Weedle (PLF 1)",
                "prices": [],
                "product_url": "https://www.cardmarket.com/en/Pokemon/Products/Singles/Plasma-Freeze/Weedle-PLF1"
            }
        }
        

Disambiguation Response:

Some set codes (e.g., "PR") are shared by multiple sets with different set_ids. When this happens, instead of returning a single set, the API returns a disambiguation response listing all matching sets so you can pick the right one.

200 OK — Multiple matches
{
  "disambiguation": true,
  "message": "Multiple sets found for set_code 'PR'. Use set_id to specify which one.",
  "matches": [
    {
      "set_id": "1938",
      "set_code": "PR",
      "name": "Alternate Art Promos",
      "language": "eng",
      "release_date": null
    },
    {
      "set_id": "1451",
      "set_code": "PR",
      "name": "XY Promos",
      "language": "eng",
      "release_date": null
    },
    {
      "set_id": "1407",
      "set_code": "PR",
      "name": "Black and White Promos",
      "language": "eng",
      "release_date": null
    }
  ],
  "total": 21
}
Tip: When you receive a disambiguation response, pick the set_id of the set you need and call /sets/1938 (using the numeric set_id) to get that specific set with its cards.
GET/sets/:setCode/image

Retrieve the logo/image for a set. Returns binary image data (PNG). Not all sets have an image available.

Parameters:

ParameterTypeRequiredDescription
setCodestringRequiredSet identifier — accepts either set_code (e.g., SWSH3) or numeric set_id (e.g., 23456). Both are returned by the /sets endpoint.
languagestringOptionalRequired only when a set_code is shared by multiple sets (e.g., eng, jap). Not needed when using a numeric set_id.

Response Headers:

  • Content-Type: image/png
  • Cache-Control: public, max-age=86400

Example Request:

curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/sets/SWSH3/image" \
     --output swsh3.png

Error Responses:

404 — Image not available
{
  "error": "Image not available",
  "message": "No set image is available for this set."
}
409 — Ambiguous set code
{
  "error": "Ambiguous set code",
  "message": "Multiple sets found for set_code 'SM11'. Add ?language=eng (or jap, etc.) to disambiguate, or use a numeric set_id.",
  "matches": [
    { "set_id": "2464", "language": "eng" },
    { "set_id": "23690", "language": "jap" }
  ]
}
Tip: Use a numeric set_id (e.g., /sets/23456/image) to always get a unique result without disambiguation.
GET/sets/:setCode/statisticsPRO

Get complete price statistics and rarity breakdown for a set. Returns average, min and max prices from both TCGPlayer (USD) and CardMarket (EUR), plus the most expensive card and a 7-day trend direction.

Pro plan required. Available on Pro and Business plans. Upgrade your plan to unlock this endpoint.

Parameters:

ParameterTypeRequiredDescription
setCodestringRequiredNumeric group_id (23599) or alphanumeric set code (sv2a)
variantstringOptionalFilter CardMarket prices by variant: normal, holo. Does not affect TCGPlayer data.

Example Request:

cURL
curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/sets/23599/statistics"

Response Example:

200 OK
{
  "set_info": {
    "name": "SV2a_ Pokemon Card 151",
    "set_code": "23599",
    "total_cards": 524
  },
  "price_statistics": {
    "tcgplayer": {
      "avg_market_price": "7.80",
      "min_price": 0.07,
      "max_price": 307.56,
      "most_expensive": { "name": "Charizard ex - 201/165", "price": 307.56 }
    },
    "cardmarket": {
      "avg_price": "2.34",
      "min_price": 0.37,
      "max_price": 17.91,
      "trend_direction": "up"
    }
  },
  "rarity_breakdown": {
    "Common": 199,
    "Uncommon": 186,
    "Rare": 77,
    "Double Rare": 12,
    "Art Rare": 18,
    "Super Rare": 16,
    "Special Art Rare": 8,
    "Ultra Rare": 3,
    "Unknown": 5
  }
}
GET/sets/:setCode/completion-valuePRO

Calculates the estimated cost to complete a set by buying one copy of every card. Returns separate estimates for TCGPlayer (USD) and CardMarket (EUR) — no cross-currency conversion is performed. Includes a breakdown by rarity.

Pro plan required. Available on Pro and Business plans. Upgrade your plan to unlock this endpoint.

Parameters:

ParameterTypeRequiredDescription
setCodestringRequiredNumeric group_id (23599) or alphanumeric set code (sv2a). CardMarket-only sets (negative group_id) return 404.

Example Request:

cURL
curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/sets/23599/completion-value"

Response Example:

200 OK
{
  "set_info": {
    "name": "SV2a_ Pokemon Card 151",
    "set_code": "23599",
    "total_cards": 524
  },
  "completion_cost": {
    "tcgplayer": {
      "currency": "USD",
      "low_estimate": 4516.16,
      "market_estimate": 4056.03,
      "high_estimate": 13687.29
    },
    "cardmarket": {
      "currency": "EUR",
      "low_estimate": 683.50,
      "avg_estimate": 1232.46,
      "trend_estimate": 1526.69
    },
    "note": "TCGPlayer prices in USD, CardMarket prices in EUR. Cross-currency comparison not available."
  },
  "breakdown_by_rarity": {
    "Common": { "count": 199, "total_cost": 950.32 },
    "Uncommon": { "count": 186, "total_cost": 732.37 },
    "Rare": { "count": 77, "total_cost": 645.50 },
    "Double Rare": { "count": 12, "total_cost": 8.29 },
    "Art Rare": { "count": 18, "total_cost": 254.25 },
    "Super Rare": { "count": 16, "total_cost": 85.38 },
    "Special Art Rare": { "count": 8, "total_cost": 893.35 },
    "Ultra Rare": { "count": 3, "total_cost": 31.02 },
    "Unknown": { "count": 5, "total_cost": 12.47 }
  }
}
404 — CardMarket-only set
{
  "success": false,
  "error": "This is a CardMarket-only set without TCGPlayer pricing data"
}

Analytics Endpoints

Authentication Required: All Analytics endpoints require an API key.
GET/analytics/top-cardsComing Soon

Get top cards ranked by price or value growth over 7 or 30-day periods.

⏳ This endpoint is currently in development and will be available soon after thorough testing.

Images Endpoint

Authentication Required: The Images endpoint requires an API key.
GET/images/:id

Retrieve card images by card ID with automatic fallback system. Returns binary image data (JPEG/PNG). Supports both TCG card IDs (pk_xxx) and CardMarket-only card IDs (no prefix).

Parameters:

ParameterTypeRequiredDescription
idstringRequiredCard ID - Two formats supported:
  • TCG cards: pk_xxx (with prefix)
  • CardMarket-only: hexadecimal hash (no prefix)
Obtained from /search, /cards/:id, or /sets/:setCode
sizestringOptionalImage size: low (~500px, ~50KB) or high (~1000px, ~200KB). Default: low

Response Headers:

  • Content-Type: image/jpeg or image/png

Example Requests:

TCG Card (with pk_ prefix):
High Resolution TCG Card
curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/images/pk_72046138a4c1908a9f27c93fdd8189ba4ac8e683efaed6b9161efcef129302394a9ec1d20d?size=high" \
     --output pikachu_tcg.jpg
CardMarket-Only Card (no prefix):
CardMarket-Only Card Image
curl -H "X-API-Key: pk_live_your_key_here" \
     "https://api.pokewallet.io/images/8eb728bd59d4e1a0d94c354e4cc65a7465b55cfa4261bfa93301faa5ec921f97?size=high" \
     --output cubone_v1.jpg
Unique IDs for Variants: Each CardMarket variant (V1, V2, etc.) has its own unique ID, so you don't need to use a set parameter for disambiguation. The ID itself uniquely identifies the exact card variant you want.

Example Response (Headers):

HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 123456

[Binary image data]

Code Examples

JavaScript (Fetch)
const API_KEY = process.env.POKEWALLET_API_KEY;
const BASE_URL = 'https://api.pokewallet.io';

async function searchCards(query) {
  const response = await fetch(`${BASE_URL}/search?q=${encodeURIComponent(query)}`, {
    headers: {
      'X-API-Key': API_KEY
    }
  });

  if (!response.ok) {
    if (response.status === 429) {
      throw new Error('Rate limit exceeded');
    }
    throw new Error(`API error: ${response.status}`);
  }

  const data = await response.json();
  return data;
}

async function getCardImage(cardId, size = 'high') {
  const url = `${BASE_URL}/images/${cardId}?size=${size}`;

  const response = await fetch(url, {
    headers: {
      'X-API-Key': API_KEY
    }
  });

  if (!response.ok) {
    throw new Error(`Failed to fetch image: ${response.status}`);
  }

  // Return blob for display or download
  const blob = await response.blob();
  return blob;
}

// Usage - Search TCG cards
searchCards('pikachu')
  .then(data => {
    console.log('TCG card results:', data);
    // IDs will have pk_ prefix
  })
  .catch(error => console.error(error));

// Usage - Search CardMarket-only cards
searchCards('cubone cbb3c')
  .then(data => {
    console.log('CardMarket-only results:', data);
    // IDs will NOT have pk_ prefix
  })
  .catch(error => console.error(error));

// Usage - Get Image (TCG card with pk_ prefix)
getCardImage('pk_72046138a4c1908a9f27c93fdd8189ba...', 'high')
  .then(blob => {
    const imageUrl = URL.createObjectURL(blob);
    document.querySelector('img').src = imageUrl;
  })
  .catch(error => console.error(error));

// Usage - Get Image (CardMarket-only, no prefix)
getCardImage('8eb728bd59d4e1a0d94c354e4cc65a74...', 'high')
  .then(blob => {
    const imageUrl = URL.createObjectURL(blob);
    document.querySelector('img').src = imageUrl;
  })
  .catch(error => console.error(error));

Error Handling

The API uses standard HTTP status codes to indicate success or failure:

200
OK

Request successful

400
Bad Request

Invalid parameters or malformed request

401
Unauthorized

Missing or invalid API key

429
Too Many Requests

Rate limit exceeded

500
Internal Server Error

Something went wrong on our side

Error Response Format

{
  "error": "Error type",
  "message": "Human-readable error description",
  "details": {
    // Additional error information (optional)
  }
}

Best Practices

Use Environment Variables

Never hardcode API keys. Always use environment variables or secure secret management.

Handle Rate Limits Gracefully

Implement exponential backoff when you receive a 429 response. Check rate limit headers to avoid hitting limits.

Cache Results

Cache API responses when appropriate to reduce requests and improve performance.

Use Search Endpoint

Always use /search for the most complete and accurate data.

Monitor Your Usage

Check your dashboard regularly to track API usage and avoid unexpected rate limit hits.

Error Handling

Always implement proper error handling for network failures, rate limits, and invalid responses.

Security Reminder: Keep your API keys secure. If you suspect a key has been compromised, revoke it immediately from your dashboard and generate a new one.

Need Help?

If you have questions or run into issues, we're here to help!