BinderDex API

Quickstart

A proposed card and sealed-product lookup workflow.

Walk through a nightly inventory review

This is a design walkthrough. The example hostname intentionally does not resolve, and no API key is available. Read the responses to evaluate the integration; these commands will not call a working service.

1. Match cards and sealed inventory

The proposed catalog endpoint includes Pokémon and One Piece cards and sealed products. This unfiltered synthetic page illustrates all three inventory examples:

Preview code examplebash
curl 'https://api.binderdex.invalid/v1/products?limit=20' \
  -H "X-API-Key: $BINDERDEX_API_KEY"

A card match is a candidate. Verify its game, set, collector number, printing, language, and market. For sealed products, verify edition, package type, units per package, and unit kind. Do not match inventory by name alone.

Synthetic product list responsejson
{
  "data": [
    {
      "id": "bdp_demo_151_bundle_en",
      "kind": "sealed",
      "name": "Demo 151 Booster Bundle",
      "game": "pokemon",
      "language": "en",
      "market": "US",
      "package_type": "booster_bundle",
      "units_per_package": 6,
      "unit_kind": "booster_pack",
      "edition": "standard",
      "condition": "factory_sealed",
      "identifiers": [
        {
          "namespace": "tcgplayer_product",
          "value": "900001"
        }
      ],
      "catalog_updated_at": "2026-09-06T11:00:00Z"
    },
    {
      "id": "bdp_demo_luffy_en",
      "kind": "card",
      "name": "Monkey D. Luffy — Demo Alternate Art",
      "game": "one_piece",
      "language": "en",
      "market": "US",
      "set": {
        "id": "set_demo_op06_en",
        "name": "Demo OP-06 Set"
      },
      "collector_number": "OP06-118",
      "printing": "alternate_art",
      "price_options": [
        {
          "variant": "foil",
          "condition": "near_mint"
        }
      ],
      "identifiers": [
        {
          "namespace": "tcgplayer_product",
          "value": "900004"
        }
      ],
      "catalog_updated_at": "2026-09-06T11:00:00Z"
    },
    {
      "id": "bdp_demo_pikachu_en",
      "kind": "card",
      "name": "Pikachu — Demo Full Art",
      "game": "pokemon",
      "language": "en",
      "market": "US",
      "set": {
        "id": "set_demo_paldea_en",
        "name": "Demo Paldea Collection"
      },
      "collector_number": "198/193",
      "printing": "Demo Full Art",
      "price_options": [
        {
          "variant": "normal",
          "condition": "near_mint"
        },
        {
          "variant": "normal",
          "condition": "lightly_played"
        }
      ],
      "identifiers": [
        {
          "namespace": "tcgplayer_product",
          "value": "900003"
        }
      ],
      "catalog_updated_at": "2026-09-06T11:00:00Z"
    }
  ],
  "pagination": {
    "next_cursor": null
  },
  "meta": {
    "request_id": "req_example",
    "snapshot_at": "2026-09-06T12:00:00Z",
    "billable_units": 1,
    "idempotent_replay": false
  }
}

To narrow an external-identifier lookup, use ?game=pokemon&kind=card&tcgplayer_id=900003&limit=20; use game=one_piece for One Piece. These aliases and IDs are invented for the preview. An alias can return multiple candidates, so do not automatically choose the first match.

Keep the opaque BinderDex product ID in your inventory mapping. For each card, also retain the exact variant and condition from price_options that matches your inventory item. A collector number does not identify alternate art on its own, and ungraded does not mean Near Mint.

2. Request the mapped products together

Save the following synthetic request as price-request.json. It selects a Pokémon card, a One Piece card, and a sealed product together. Card selections require a variant and condition; sealed selections do not accept those card fields.

Synthetic batch request bodyjson
{
  "items": [
    {
      "kind": "card",
      "product_id": "bdp_demo_pikachu_en",
      "variant": "normal",
      "condition": "near_mint"
    },
    {
      "kind": "card",
      "product_id": "bdp_demo_luffy_en",
      "variant": "foil",
      "condition": "near_mint"
    },
    {
      "kind": "sealed",
      "product_id": "bdp_demo_151_bundle_en"
    }
  ]
}
Preview code examplebash
curl 'https://api.binderdex.invalid/v1/prices/batch' \
  -H "X-API-Key: $BINDERDEX_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: inventory-review-example-001' \
  --data @price-request.json

The example key is a job identifier, not an API credential. Use a new idempotency key for each new job. Retrying the same batch within the proposed retention window reuses its key and body.

The batch reference defines input-order preservation and all response shapes. A successful HTTP response can still contain stale, unknown, or missing items. This example has a fresh Pokémon card price, a stale One Piece card price, and a missing sealed-product price:

Synthetic mixed batch responsejson
{
  "data": [
    {
      "selection": {
        "kind": "card",
        "product_id": "bdp_demo_pikachu_en",
        "variant": "normal",
        "condition": "near_mint"
      },
      "status": "fresh",
      "price": {
        "amount_cents": 1250,
        "currency": "USD"
      },
      "observation": {
        "source": "licensed_reference",
        "source_as_of": "2026-09-06T10:00:00Z",
        "collected_at": "2026-09-06T11:00:00Z",
        "basis": "market_reference",
        "attribution": "Synthetic preview observation — no provider data."
      },
      "missing_reason": null
    },
    {
      "selection": {
        "kind": "card",
        "product_id": "bdp_demo_luffy_en",
        "variant": "foil",
        "condition": "near_mint"
      },
      "status": "stale",
      "price": {
        "amount_cents": 2080,
        "currency": "USD"
      },
      "observation": {
        "source": "licensed_reference",
        "source_as_of": "2026-09-04T00:00:00Z",
        "collected_at": "2026-09-04T01:00:00Z",
        "basis": "market_reference",
        "attribution": "Synthetic preview observation — no provider data."
      },
      "missing_reason": null
    },
    {
      "selection": {
        "kind": "sealed",
        "product_id": "bdp_demo_151_bundle_en"
      },
      "status": "missing",
      "price": null,
      "observation": null,
      "missing_reason": "no_observation"
    }
  ],
  "meta": {
    "request_id": "req_example",
    "snapshot_at": "2026-09-06T12:00:00Z",
    "billable_units": 1,
    "idempotent_replay": false
  }
}

3. Separate usable prices from manual review

Use integer cents for calculations. A missing or unusable price is not zero. Even a fresh reference price is informational; it is not a guaranteed sale price or an instruction to change a shop’s prices automatically.

Preview code examplejs
// Preview logic after matching the exact sellable unit.
function reviewPrice(result) {
  if (
    result.status !== "fresh" ||
    result.price?.currency !== "USD" ||
    !Number.isSafeInteger(result.price?.amount_cents) ||
    result.price.amount_cents < 0
  ) {
    return { selection: result.selection, action: "manual_review" };
  }

  return {
    selection: result.selection,
    action: "compare_reference",
    amountCents: result.price.amount_cents,
  };
}

Before using a result, confirm that its complete selection matches the requested position: product ID and kind, plus variant and condition for a card. Keep currency explicit. If you total multiple items, validate quantities and guard the resulting integer against overflow.

You can request two conditions of the same card in one batch, but not the exact same selection twice. If the catalog does not support the selected condition or variant, the item is missing with unsupported_selection. Do not silently substitute Near Mint, a different finish, or an ungraded reference.

4. Handle failures deliberately

A 401 requires checking the key. A 403 requires checking its scope. A 409 can mean that an idempotency key was reused with a different batch. A 429 distinguishes a short-term rate limit from an exhausted quota; neither should create an unbounded retry loop.

For a temporary service error, keep the last successful record labeled with its observation time and leave the current item for review. See errors and versioning for the proposed envelopes.

What would make this fit your system?

If your integration needs a particular Pokémon or One Piece printing, condition, identifier, sealed package, freshness interval, or batch size, describe that requirement. Those details will help shape the first release.