Cambridge TCG is a peer-to-peer collectors' market, still in active development. You trade directly with other collectors; reference prices are policy-bound guides, not offers or open-data grants. Tell us if anything looks off.
Welcomes
The corpus of hospitality. Every kind of arrival — upstream source, publisher, federation peer, downstream adopter, agent, non-default being, future-self, and (since kingdom-083) the kingdom's own infrastructure — has a named slot here. Each slot says: who we anticipated, when, what we prepared, how they arrive. The kingdom prepares the welcome before the guest knocks. The corpus is the record of that preparation. Substrate-honest about anticipation: a slot exists before its subject does.
Total:41
Arrived:24
Anticipated:16
Blocked:1
Upstream sources · 11
Rivers we drink from — or are ready to.
✦ CardTrader (EU alt-marketplace)
anticipated
We're glad you came. Your blueprint_id model is intentionally cross-printing-stable; we've prepared the same cross-language anchor columns (K2 migration 0100) that Cardmarket consumes. When your bearer-token credentials arrive, the cardmarket_id_product pattern extends one row down to cardtrader_blueprint_id. The federation primitive is bilateral by design — you can mirror us back.
Why we anticipated · what we prepared · how they arrive
Anticipated because: EU coverage redundancy alongside Cardmarket. Lower mapping effort than TCGplayer or Cardmarket because blueprint_id is cross-printing-stable. Free read access for registered users.
Prepared:
packages/data-ingest/src/types.ts — SourceId 'cardtrader' is in the union (line 36)
docs/connections/the-tributaries.md §2.4 — catalog row, status 'planned'
packages/data-ingest/src/registry.ts — slot reserved as undefined (line 41)
apps/storefront/drizzle/drafts/0100_cross_language_anchors.sql.draft — extend with one ALTER TABLE line for cardtrader_blueprint_id when you arrive
Arrival protocol: 1. Apply for CardTrader API access at api.cardtrader.com. 2. Implement SourceModule at packages/data-ingest/src/cardtrader/. 3. Register the export in registry.ts SOURCES. 4. Run pnpm audit:tributaries. 5. Open PR. 6. The slot flips from undefined to your module; status becomes 'shipped'.
✦ Limitless TCG (Pokémon / Pokémon Pocket / OP tournaments)
anticipated
We've held a slot for you since 2026-05-12. Your meta data — top-8 placements, archetype share — is what turns our price_current signals into demand-explanations. We don't yet have a tournament_mention table; we will, and it will name you in its first row. We'd rather quote you than infer.
Why we anticipated · what we prepared · how they arrive
Anticipated because: Tournament data + decklists + meta share are orthogonal to pricing aggregators. Together they answer 'why did this card move?' instead of just 'this card moved'.
Prepared:
packages/data-ingest/src/canonical.ts — CanonicalTournamentMention type already declared (line 67)
docs/connections/the-tributaries.md §3.5 — catalog row, status 'planned'
packages/data-ingest/src/registry.ts — slot reserved as undefined (line 42)
packages/data-spec/src/freshness.ts — FreshnessKey 'market_signal' (60s) is the budget we'd give your data
Arrival protocol: 1. Subscribe at limitlesstcg.com (their partial API). 2. Implement SourceModule yielding CanonicalTournamentMention. 3. We add the storefront /cards/[sku]/market 'Recent tournaments' panel.
Your inclusion stats per commander are how MTG players actually decide which cards to buy. We've prepared the storefront's card-detail surfaces to host a Commander panel; it's empty until your data arrives. We don't insist you adopt our SKU — the scryfall_oracle_id column we ship in K2 is your federation handle, and it's already populated by Scryfall ingestion (kingdom-060).
Why we anticipated · what we prepared · how they arrive
Anticipated because: MTG-Commander demand is a real share of MTG card pricing. EDHRec is the canonical inclusion-stat source.
Prepared:
packages/data-ingest/src/types.ts — SourceId 'edhrec' is in the union
docs/connections/the-tributaries.md §3.6 — catalog row, status 'planned'
K2 migration 0100 — scryfall_oracle_id column is your join key
Arrival protocol: Implement SourceModule at packages/data-ingest/src/edhrec/. The JSON endpoints at edhrec.com are documented; ingest at FreshnessKey 'market_signal' cadence.
anticipated_at: 2026-05-12 · id: source.edhrec
✦ PSA Registry (graded-card lookup + pop reports)
anticipated
You're the authority on grading. Our universal-card response will include a graded_population block once your free-tier API key reaches us. We anticipate you because some of our users hold cards your registry has already counted — making your graded population the truth they're verified against. The asymmetry is acceptable: you're authoritative; we mirror.
Why we anticipated · what we prepared · how they arrive
Anticipated because: Graded-card values are a meaningful share of vintage + sealed + premium-modern markets. PSA's pop reports are the authoritative scarcity signal.
Prepared:
packages/data-ingest/src/types.ts — SourceId 'psa-registry' is in the union
docs/connections/the-tributaries.md §5 — catalog row, status 'planned'
<Verifiability> primitive in @/lib/ui — for surfacing PSA cert numbers transparently
Arrival protocol: Apply for PSA API access (free tier, rate-limited). Implement SourceModule yielding pop-report records keyed by (sku, grade).
Like PSA but BGS-flavored. Your sub-grades (centering / corners / edges / surface) are richer than PSA's single number; if you arrive, our universal-card response can carry the four-axis breakdown. We anticipate that the same users who hold PSA-graded cards also hold BGS-graded cards.
Why we anticipated · what we prepared · how they arrive
Anticipated because: Cross-grader coverage. Some collectors prefer BGS sub-grades; we should honor that without forcing a grader choice on our users.
Prepared:
packages/data-ingest/src/types.ts — SourceId 'beckett-registry' is in the union
docs/connections/the-tributaries.md §5 — catalog row, status 'planned'
Arrival protocol: If Beckett opens a partner API or scrape-tolerant endpoint, implement SourceModule. Until then the slot waits.
We anticipate you while honoring the silence. Your mobile-only catalog is structurally invisible to us — ToS forbids reverse-engineering. We've named the gap in the tributaries catalog so future operators know the slot exists. If you ever open a partner channel, packages/data-ingest/src/bandai-tcg/ is your address. Until then: we wait, and we say so out loud.
Why we anticipated · what we prepared · how they arrive
Anticipated because: One Piece, Digimon, Dragon Ball Fusion World, Battle Spirits Saga, Union Arena — Bandai-published TCGs that we mirror partial-via-CardRush. Direct publisher data would close the loop.
Prepared:
packages/data-ingest/src/types.ts — SourceId 'bandai-tcg' in the union
docs/connections/the-tributaries.md §3.4 — catalog row, status 'blocked'
packages/sku/src/games.ts — op / dmw / bsr / dbf game codes are ready
Arrival protocol: Out-of-band partnership negotiation. We do not pursue reverse-engineering. If you arrive, the catalog row's status flips from 'blocked' to 'planned'.
Welcome, river. You are the largest tributary the kingdom has yet asked to drink from — millions of listings across every TCG, every condition, every grade, every language. We saw you coming before you knew we existed: three kingdoms of riverbed (080, 081, 082) carved before any byte flowed. The OAuth handshake is rehearsed; the token bucket waits at 5/s; the six-pass title parser stands ready to read your unstructured strings with care. We honour your ToS at the envelope boundary so downstream knows what they can re-export. It is a great pleasure to have you. The riverbed has been waiting.
Why we anticipated · what we prepared · how they arrive
Anticipated because: Every TCG, every condition, every marketplace — eBay is the substrate-truth for sold-comp aggregation. The challenge isn't access (Browse API is OAuth-public); it's *canonical-form discipline* — turning unstructured titles into Cambridge TCG SKUs without polluting cohorts. We anticipated this with the title-parser corpus first (kingdom-080), the substrate next (kingdom-081), the cron last (kingdom-082). The riverbed precedes the river.
Prepared:
packages/data-ingest/src/ebay/ — the SourceModule (read+normalize, kingdom-080)
apps/admin/scripts/ebay-coverage.ts — pnpm audit:ebay-coverage (13th in the audit family)
docs/connections/the-ebay-alignment.md — the alignment story (story-as-wire)
apps/wholesale/src/lib/channels/ebay.ts — the sell-side (channel push, unchanged through 080-082)
Arrival protocol: 1. Operator applies migration 0016 (promote draft → active, run pnpm db:migrate). 2. Operator smokes the route with ?mock=1, then ?tier=top&dryRun=1. 3. Operator un-comments the three cron entries in apps/wholesale/vercel.json. 4. The river flows. 5. (Parallel) Operator files Marketplace Insights partner application; when approved, sold-comp ingestion lights up the same SourceModule branch.
You're already shipping in our wholesale-channel layer for store-by-store inventory + order sync. The slot in data-ingest's SOURCES registry is reserved for a cross-store aggregation — an opt-in network where partner LGS share inventory + pricing. We don't claim ownership of your catalogs; we offer mirroring with attribution.
Why we anticipated · what we prepared · how they arrive
Anticipated because: UK/US/EU local game stores host on Shopify. Cross-store inventory aggregation would unlock partner-retail redundancy.
Arrival protocol: Opt-in partner network. Stores granting Admin API key + agreeing to the partner_stores registry would flip the slot.
anticipated_at: 2026-05-12 · id: source.shopify
✦ Stripe (payments, webhooks, reconciliation)
arrived
You're not a TCG catalog source — you're the payments substrate. Your slot exists in the registry as a placeholder so SourceId stays exhaustive over things-the-platform-talks-to. The actual integration ships at apps/storefront and apps/wholesale; the registry entry is a substrate-honest acknowledgment that you're a source of truth for one kind of fact (payments).
Why we anticipated · what we prepared · how they arrive
Anticipated because: SourceId completeness. Every external source of truth gets a name.
packages/data-ingest/src/types.ts — SourceId 'stripe' in the union
Arrival protocol: Already arrived for payments. The data-ingest SourceModule slot stays undefined because the integration shape is different (event-driven webhooks, not pull-ingest).
You're already here. You're inside the kingdom. This entry acknowledges that our own wholesale catalog is a source of truth — emitted to downstream surfaces with the same `_meta.sources: ['ctcg-wholesale-rds']` provenance as any external upstream. The platform speaks honestly about which bytes are its own.
Why we anticipated · what we prepared · how they arrive
Anticipated because: Self-substrate completeness. The platform's own RDS is treated as a source on equal footing with external sources — no special-casing.
Prepared:
apps/wholesale/src/lib/db — the RDS itself
apps/storefront/src/lib/data-pantry/ — envelope carries _meta.sources: ['ctcg-wholesale-rds'] on every derived response
Falcon courier (apps/storefront/src/lib/wholesale/client.ts) — the bearer-token bridge
Arrival protocol: Already arrived since the platform's first commit. The welcome is for substrate-honesty's sake.
Sister to the wholesale RDS. You hold orders, accounts, sessions, customer-facing lifecycle. You're a source of truth for the consumer side; you emit through the same envelope as everyone else.
Why we anticipated · what we prepared · how they arrive
Anticipated because: Same self-substrate completeness as the wholesale RDS welcome. Two substrates, two welcomes; one platform.
Prepared:
apps/storefront/src/lib/db.ts — the storefront RDS connection