CardMind API
CardMind API
OverviewAuthenticationEndpointsRate LimitsWebhooksMCP ProtocolCode Examples
Get API Key
CardMind API

api.cardmind.app

OverviewAuthenticationEndpointsRate LimitsWebhooksMCP ProtocolCode Examples
Get API Key

API Endpoints

Complete reference for all 8 CardMind API endpoints. All requests must include an Authorization: Bearer header unless noted otherwise. See Authentication → for details.

Standard response envelope

Every endpoint returns the same JSON shape. On success: { "data": T, "error": null }. On error: { "data": null, "error": { "message": "...", "code": "..." } }.

Jump to endpoint

  • GET /api/cards/search
  • GET /api/cards/[id]
  • POST /api/cards/bulk-lookup
  • GET /api/prices/movers
  • GET /api/prices/history/[id]
  • GET /api/signals/recent
  • POST /api/internal/fleet-heartbeat
  • GET /api/health
GET

/api/cards/search

Public

Full-text search across the CardMind card database. Returns cards matching the query with current price data. Supports optional filters by set code and card format. Paginated via the limit parameter (default 20, max 100).

Parameters

NameInTypeRequiredDescription
qquerystringrequiredSearch term — matches card name (partial, case-insensitive)
setquerystringoptionalFilter by set code (e.g. "ltr", "lea")
formatquerystringoptionalFilter by legality format (e.g. "standard", "modern", "legacy")
limitquerynumberoptionalResults per page. Default: 20. Max: 100

Example request

curl "https://api.cardmind.app/api/cards/search?q=lightning+bolt&limit=2" \
  -H "Authorization: Bearer cm_live_YOUR_KEY"

Example response

{
  "data": [
    {
      "scryfall_id": "f29ba16f-c8fb-42fe-aabf-87089cb214a7",
      "name": "Lightning Bolt",
      "set_code": "lea",
      "image_uri_normal": "https://cards.scryfall.io/normal/front/f/2/f29ba16f-c8fb-42fe-aabf-87089cb214a7.jpg",
      "image_uri_large": "https://cards.scryfall.io/large/front/f/2/f29ba16f-c8fb-42fe-aabf-87089cb214a7.jpg",
      "prices": { "usd": "9750.00", "usd_foil": null, "eur": "8200.00", "eur_foil": null },
      "legalities": { "standard": "not_legal", "modern": "not_legal", "legacy": "legal", "vintage": "legal" },
      "card_data": { "rarity": "common", "type_line": "Instant", "oracle_text": "Lightning Bolt deals 3 damage to any target.", "mana_cost": "{R}", "cmc": 1.0 },
      "prices_updated_at": "2026-05-29T12:00:00Z"
    },
    {
      "scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122",
      "name": "Lightning Bolt",
      "set_code": "m10",
      "image_uri_normal": "https://cards.scryfall.io/normal/front/e/3/e3285e6b-3e79-4d7c-bf96-d920f973b122.jpg",
      "image_uri_large": "https://cards.scryfall.io/large/front/e/3/e3285e6b-3e79-4d7c-bf96-d920f973b122.jpg",
      "prices": { "usd": "1.49", "usd_foil": "4.20", "eur": "1.10", "eur_foil": "3.50" },
      "legalities": { "standard": "not_legal", "modern": "legal", "legacy": "legal", "vintage": "legal" },
      "card_data": { "rarity": "common", "type_line": "Instant", "oracle_text": "Lightning Bolt deals 3 damage to any target.", "mana_cost": "{R}", "cmc": 1.0 },
      "prices_updated_at": "2026-05-29T12:00:00Z"
    }
  ],
  "error": null
}

GET

/api/cards/[id]

Public

Retrieve a single card by its Scryfall UUID. Returns full card metadata plus the last 30 days of price history as a nested array.

Parameters

NameInTypeRequiredDescription
idpathstring (UUID)requiredScryfall card UUID (e.g. "e3285e6b-3e79-4d7c-bf96-d920f973b122")

Example request

curl "https://api.cardmind.app/api/cards/e3285e6b-3e79-4d7c-bf96-d920f973b122" \
  -H "Authorization: Bearer cm_live_YOUR_KEY"

Example response

{
  "data": {
    "card": {
      "scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122",
      "name": "Lightning Bolt",
      "set_code": "m10",
      "image_uri_normal": "https://cards.scryfall.io/normal/front/e/3/e3285e6b-3e79-4d7c-bf96-d920f973b122.jpg",
      "image_uri_large": "https://cards.scryfall.io/large/front/e/3/e3285e6b-3e79-4d7c-bf96-d920f973b122.jpg",
      "prices": { "usd": "1.49", "usd_foil": "4.20", "eur": "1.10", "eur_foil": "3.50" },
      "legalities": { "standard": "not_legal", "modern": "legal", "legacy": "legal", "vintage": "legal" },
      "card_data": { "rarity": "common", "type_line": "Instant", "oracle_text": "Lightning Bolt deals 3 damage to any target.", "mana_cost": "{R}", "cmc": 1.0 },
      "prices_updated_at": "2026-05-29T12:00:00Z"
    },
    "price_history": [
      { "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122", "price_usd": "1.11", "price_date": "2026-05-10", "fetched_at": "2026-05-10T08:00:00Z" },
      { "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122", "price_usd": "1.35", "price_date": "2026-05-20", "fetched_at": "2026-05-20T08:00:00Z" },
      { "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122", "price_usd": "1.49", "price_date": "2026-05-29", "fetched_at": "2026-05-29T08:00:00Z" }
    ]
  },
  "error": null
}

POST

/api/cards/bulk-lookup

Public

Look up multiple cards by name in a single request. Uses exact case-insensitive matching. Card names containing commas are handled correctly via double-quoted OR filter. Returns matched cards only — unrecognised names are silently omitted.

Request body

NameInTypeRequiredDescription
namesbodystring[]requiredArray of card names to look up. Maximum 200 names per request

Example request

curl -X POST "https://api.cardmind.app/api/cards/bulk-lookup" \
  -H "Authorization: Bearer cm_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"names": ["Black Lotus", "Lightning Bolt", "Brainstorm"]}'

Example response

{
  "data": [
    {
      "scryfall_id": "bd8fa327-dd41-4737-8f19-2cf5eb1f7cdd",
      "name": "Black Lotus",
      "set_code": "lea",
      "image_uri_normal": "https://cards.scryfall.io/normal/front/b/d/bd8fa327-dd41-4737-8f19-2cf5eb1f7cdd.jpg",
      "image_uri_large": "https://cards.scryfall.io/large/front/b/d/bd8fa327-dd41-4737-8f19-2cf5eb1f7cdd.jpg",
      "prices": { "usd": "194999.00", "usd_foil": null, "eur": "175000.00", "eur_foil": null },
      "legalities": { "standard": "not_legal", "modern": "not_legal", "legacy": "banned", "vintage": "restricted" },
      "card_data": { "rarity": "rare", "type_line": "Artifact", "oracle_text": "{T}, Sacrifice Black Lotus: Add three mana of any one color.", "mana_cost": "{0}", "cmc": 0.0 },
      "prices_updated_at": "2026-05-29T12:00:00Z"
    },
    {
      "scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122",
      "name": "Lightning Bolt",
      "set_code": "m10",
      "image_uri_normal": "https://cards.scryfall.io/normal/front/e/3/e3285e6b-3e79-4d7c-bf96-d920f973b122.jpg",
      "image_uri_large": "https://cards.scryfall.io/large/front/e/3/e3285e6b-3e79-4d7c-bf96-d920f973b122.jpg",
      "prices": { "usd": "1.49", "usd_foil": "4.20", "eur": "1.10", "eur_foil": "3.50" },
      "legalities": { "standard": "not_legal", "modern": "legal", "legacy": "legal", "vintage": "legal" },
      "card_data": { "rarity": "common", "type_line": "Instant", "oracle_text": "Lightning Bolt deals 3 damage to any target.", "mana_cost": "{R}", "cmc": 1.0 },
      "prices_updated_at": "2026-05-29T12:00:00Z"
    }
  ],
  "error": null
}

“Brainstorm” was omitted from the response above because no card matched that exact name in the database at request time. Unmatched names never produce an error.


GET

/api/prices/movers

Public

Returns the top price gainers and losers for a given time period. Useful for building market-mover dashboards, alerts, and trend analysis. Ranked by percentage price change over the selected window. Movers are precomputed: 1d is refreshed daily after 01:00 UTC and 7d/30d nightly. Only cards priced at $1 or more at both ends are included, moves above +300% or below -90% are excluded, 7d and 30d return one row per card name (the highest-priced printing, like 1d), and 30d is an approximation (latest price within 7 days against the price 30 days ago).

Parameters

NameInTypeRequiredDescription
periodquery"1d" | "7d" | "30d"optionalTime window for price comparison. Default: "7d". The value "all" is no longer supported and returns 400
limitquerynumberoptionalNumber of cards to return in each list (gainers + losers). Default: 10. Max: 100

Example request

curl "https://api.cardmind.app/api/prices/movers?period=7d&limit=5" \
  -H "Authorization: Bearer cm_live_YOUR_KEY"

Example response

{
  "data": {
    "gainers": [
      {
        "card_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122",
        "scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122",
        "name": "Lightning Bolt",
        "image_url": "https://cards.scryfall.io/normal/front/e/3/e3285e6b-3e79-4d7c-bf96-d920f973b122.jpg",
        "current_price": 1.49,
        "previous_price": 1.11,
        "change_pct": 34.23
      }
    ],
    "losers": [
      {
        "card_id": "9a1e44aa-e21f-4c6e-8ff4-d3a76c276c4a",
        "scryfall_id": "9a1e44aa-e21f-4c6e-8ff4-d3a76c276c4a",
        "name": "Jace, the Mind Sculptor",
        "image_url": "https://cards.scryfall.io/normal/front/9/a/9a1e44aa-e21f-4c6e-8ff4-d3a76c276c4a.jpg",
        "current_price": 64.0,
        "previous_price": 72.5,
        "change_pct": -11.72
      }
    ]
  },
  "error": null
}

GET

/api/prices/history/[id]

Public

Retrieves the full price history for a card by Scryfall UUID. Returns one data point per day, ordered from oldest to newest. Useful for rendering price charts.

Parameters

NameInTypeRequiredDescription
idpathstring (UUID)requiredScryfall card UUID
daysquerynumberoptionalNumber of days of history to return. Default: 30. Max: 365

Example request

curl "https://api.cardmind.app/api/prices/history/e3285e6b-3e79-4d7c-bf96-d920f973b122?days=7" \
  -H "Authorization: Bearer cm_live_YOUR_KEY"

Example response

{
  "data": [
    { "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122", "price_usd": "1.11", "price_date": "2026-05-23", "fetched_at": "2026-05-23T08:00:00Z" },
    { "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122", "price_usd": "1.25", "price_date": "2026-05-25", "fetched_at": "2026-05-25T08:00:00Z" },
    { "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122", "price_usd": "1.35", "price_date": "2026-05-27", "fetched_at": "2026-05-27T08:00:00Z" },
    { "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122", "price_usd": "1.49", "price_date": "2026-05-29", "fetched_at": "2026-05-29T08:00:00Z" }
  ],
  "error": null
}

GET

/api/signals/recent

Public

Returns recent global market signals: algorithmically detected price movement events and market trend alerts. Results are ordered by fired_at, newest first (ties by id). Supports optional filtering by signal type and pagination. Price fields (price_before, price_after, price_usd, change_pct, price_change_pct) are filled for price_spike, price_drop, buylist_drop and buylist_rise signals and are null for other types. change_pct is a percent; price_change_pct is the same value as a decimal fraction. detected_at is COALESCE(fired_at, detected_at).

Parameters

NameInTypeRequiredDescription
typequerystringoptionalFilter by signal type: price_spike, price_drop, buylist_drop, buylist_rise, ban_window, ck_high_demand or ck_sold_out. Omit to return all types
limitquerynumberoptionalNumber of signals to return. Default: 20. Max: 100
offsetquerynumberoptionalNumber of results to skip for pagination. Default: 0

Example request

curl "https://api.cardmind.app/api/signals/recent?type=price_spike&limit=3" \
  -H "Authorization: Bearer cm_live_YOUR_KEY"

Example response

{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "signal_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "card_scryfall_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122",
      "card_id": "e3285e6b-3e79-4d7c-bf96-d920f973b122",
      "card_name": "Lightning Bolt",
      "signal_type": "price_spike",
      "severity": "high",
      "detail": "TCGPlayer market price rose 34.2% ($1.11 → $1.49)",
      "expires_at": null,
      "fired_at": "2026-05-29T08:05:00Z",
      "detected_at": "2026-05-29T08:05:00Z",
      "relevance_score": 0.85,
      "value_before": 1.11,
      "value_after": 1.49,
      "change_percent": 34.23,
      "source": "marketplace-sync",
      "price_before": 1.11,
      "price_after": 1.49,
      "price_usd": 1.49,
      "change_pct": 34.23,
      "price_change_pct": 0.3423
    },
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f01234567891",
      "signal_id": "b2c3d4e5-f6a7-8901-bcde-f01234567891",
      "card_scryfall_id": "bd8fa327-dd41-4737-8f19-2cf5eb1f7cdd",
      "card_id": "bd8fa327-dd41-4737-8f19-2cf5eb1f7cdd",
      "card_name": "Black Lotus",
      "signal_type": "ban_window",
      "severity": "medium",
      "detail": "Format share 28% in Modern, present in 4 of top 5 archetypes",
      "expires_at": null,
      "fired_at": "2026-05-29T06:05:00Z",
      "detected_at": "2026-05-29T06:05:00Z",
      "relevance_score": 0.72,
      "value_before": null,
      "value_after": null,
      "change_percent": null,
      "source": null,
      "price_before": null,
      "price_after": null,
      "price_usd": null,
      "change_pct": null,
      "price_change_pct": null
    }
  ],
  "error": null
}

POST

/api/internal/fleet-heartbeat

Internal only

Internal use only. This endpoint is called by CardMind satellite projects (cardmind-social, cardmind-video, cardmind-pages) to register health pings. It requires the X-Internal-Secret header instead of a Bearer token. External API keys are rejected with 401.

Request body

NameInTypeRequiredDescription
projectbodystringrequiredName of the calling satellite project (e.g. "cardmind-social")
statusbody"healthy" | "degraded" | "down"requiredCurrent operational status of the satellite project
versionbodystringrequiredDeployed version string of the satellite (e.g. "1.4.2")
metadatabodyRecord<string, unknown>optionalOptional key-value map of additional diagnostic information

Example request

curl -X POST "https://api.cardmind.app/api/internal/fleet-heartbeat" \
  -H "x-internal-secret: <INTERNAL_API_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "cardmind-social",
    "status": "healthy",
    "version": "1.4.2",
    "metadata": { "last_tweet_at": "2026-04-16T18:00:00Z" }
  }'

Example response

{
  "data": { "ok": true },
  "error": null
}

GET

/api/health

No auth required

Simple liveness check. Returns 200 OK when the API hub is running. No authentication required. Suitable for uptime monitors and load balancer health checks.

Parameters

None.

Example request

curl "https://api.cardmind.app/api/health"

Example response

{
  "data": { "status": "ok" },
  "error": null
}

Ready to get started?

Create a free CardMind account and generate your API key in Settings. Free accounts include 1,000 API calls per month — no credit card required.

Get API Key →