Your cart is empty
Browse CatalogYour sell cart is empty
Add cards from the buylist to get started
Etiquette + identification + the contact channel.
Cambridge TCG is run by one operator (Yu) on a small infrastructure budget. The data is CC0; the compute isn't. This guide names the behaviours that keep the platform happy to serve you, and the ones that get you rate-limited or banned. Substrate-honest: we'd rather give you a free, generous tier than play cat-and-mouse with bots we can't reach.
Always send a User-Agent string that names your project and a contact email. The format we recommend: `your-project/1.0 ([email protected])`. We'd rather email you about a bug than firewall an opaque bot.
Run this
curl -H 'User-Agent: example-bot/1.0 ([email protected])' \ https://cambridgetcg.com/api/v1/manifest
What to do with it
Default Python requests / Node fetch User-Agents are anonymous. Override them. We log User-Agents per IP; identified clients get a courtesy email before rate-limiting; anonymous ones don't.
Every response carries `Cache-Control: public, max-age=N`. Respect it. Our envelope also carries `_meta.freshness_seconds` as the platform's intent — `price_current=300`, `catalog=86400`, `status=30`, `methodology=86400`. Polling faster than the budget returns the same response.
What to do with it
Implement an HTTP cache (your language's `requests-cache`, `http-cache`, etc.) honouring `Cache-Control`. Or read `_meta.freshness_seconds` and schedule your next poll accordingly.
Every public response carries `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers (IETF draft standard). If you see `RateLimit-Remaining: 0`, pause until `RateLimit-Reset` seconds elapse. If you see HTTP 429, the response body's `error.retry_after` is your wait time.
What to do with it
Implement exponential back-off on 429. Respect Retry-After. Your future self will thank you.
If you find a response that doesn't match the OpenAPI spec, or a documented endpoint that doesn't exist, or a guide that's wrong, tell us. The feedback channel is POST /api/v1/feedback (no auth) or email [email protected].
Run this
curl -X POST https://cambridgetcg.com/api/v1/feedback \
-H 'content-type: application/json' \
-d '{
"kind": "contract-drift",
"endpoint": "/api/v1/...",
"observed": "actual response shape",
"expected": "per OpenAPI spec",
"reporter_contact": "[email protected]"
}'What to do with it
We read every report. If your bug is real, we fix it within a week and reply with the commit SHA. Substrate-honesty: drift between the contract and the response is *our* failure, not yours.
Auth-gated endpoints (`/api/v1/cards/[sku]/cardrush-history`, `/api/v1/webhooks/subscriptions`) check next-auth session cookies. Don't try to fake them. We log unauthorized attempts.
The HTML market pages are for humans. The math-mirror endpoint is for you. Scraping HTML costs us ~10× the compute of serving JSON and you're depending on layout that may change. The JSON contract is versioned and stable.
It's 6 MB streamed. Pulling it every minute is rude. The freshness budget is 24 hours; cron at 04:00 UTC is what we recommend.
Next guide
Implement /federation/identify on your side. We'll resolve your hashes too.