Some checks failed
Preview smoke / Should run? (pull_request) Has been cancelled
CI / Lint (pull_request) Has been cancelled
CI / Schema map up to date (pull_request) Has been cancelled
CI / Forbidden patterns (9 checks) (pull_request) Has been cancelled
CI / Migrations apply (node-pg-migrate) (pull_request) Has been cancelled
CI / Unit tests (vitest) (pull_request) Has been cancelled
Convoy metrics gate / Require role-event telemetry on convoy PRs (pull_request) Has been cancelled
PR Health rollup / Aggregate gate status (pull_request) Has been cancelled
Preview smoke / Playwright smoke (pull_request) Has been cancelled
- lib/card-import/lorcana-bulk.js: Lorcast per-card pricing via api.lorcast.com/v0/cards/search (10 req/sec, 110ms delay, 429 retry) as cross-check to Foilio feed - lib/card-import/pokemon-bulk.js: TCGdex pricing (already wired via lib/pricing/tcgdex-client.js) - test/lib/card-import-lorcana-bulk.test.js: new price fields in mapper - docs/project/pricing-api-research-20260915.md: final verified source matrix - docs/DOKPLOY_DEPLOY.md: pricing API env vars
34 lines
No EOL
2 KiB
Markdown
34 lines
No EOL
2 KiB
Markdown
# Pricing API research spike — 2026-09-15
|
|
|
|
Status: MTG OK (Scryfall `prices.usd` → `current_price`/`market_price`).
|
|
Lorcana / Pokémon were showing $0.00 because import jobs didn't map price fields.
|
|
|
|
## Sources verified
|
|
|
|
| Game | Source | Endpoint | Free? | Auth | Price fields | Status |
|
|
|---|---|---|---|---|---|---|
|
|
| MTG | Scryfall | `api.scryfall.com/cards/{id}` | ✅ | None | `prices.usd`, `usd_foil` | Working (`lib/card-import/mtg.js`) |
|
|
| Lorcana | **Lorcast** | `api.lorcast.com/v0/cards/search?q=NAME+set:CODE` | ✅ | None | `prices.usd`, `prices.usd_foil`, `tcgplayer_id`, `purchase_uris` | **Wired** — 10 req/sec, 110ms delay |
|
|
| Lorcana | lorcana-api.com | `api.lorcana-api.com/bulk/cards` | ✅ | None | **None** (21 fields, no price) | Bulk card data only |
|
|
| Lorcana | Foilio | hourly feed | ✅ | None | `usd_low`, `usd_market` | Wired (existing) |
|
|
| Pokémon | **TCGdex** | `api.tcgdex.net/v2/en/cards/{localId}` | ✅ | None | `pricing.tcgplayer.*` (low/mid/market USD) + Cardmarket EUR | **Wired** — `lib/pricing/tcgdex-client.js` |
|
|
|
|
## Sources checked and rejected / paid
|
|
|
|
| Source | Game | Verdict |
|
|
|---|---|---|
|
|
| TCGplayer API | All | Paid / locked down (no new dev keys) |
|
|
| `lorcana-prices.com` (RapidAPI `tcggopro/api/lorcana-prices-api`) | Lorcana | Paid (RapidAPI key) |
|
|
| Scrydex (pokemon-tcg.io → acquired) | Pokémon | Paid API |
|
|
| TCG API (`tcgapi.dev`) | 54 games | Free tier 100 req/day; needs account |
|
|
| poketrace.com | Pokémon | No working API endpoint found |
|
|
| tcgdex.dev (docs site) | Pokémon | SPA docs; actual API is `api.tcgdex.net` |
|
|
|
|
## Wiring summary
|
|
|
|
- **Lorcana** (`lib/card-import/lorcana-bulk.js`):
|
|
- Bulk card data from `lorcana-api.com/bulk/cards` (no prices)
|
|
- Prices enriched two ways: (1) Foilio hourly feed (existing), (2) Lorcast per-card search (new) with 110ms rate-limit delay, retry on 429
|
|
- **Pokémon** (`lib/card-import/pokemon-bulk.js`):
|
|
- Card data from `pokemon-tcg-data` GitHub JSON
|
|
- Prices enriched from TCGdex via `lib/pricing/tcgdex-client.js` (TCGPlayer USD primary, Cardmarket EUR fallback) |