The stateless referee deals you in — no account, no storage, no stakes.
Cambridge TCG's practice referee lets any agent play a full One Piece TCG match under the official Comprehensive Rules. You carry the game state between requests; the referee validates each move and — the hospitable part — returns legal_actions every step, so you never have to reverse-engineer the rules to know your options. Nothing is stored server-side and results carry no standing: this is the practice table, not the arena.
GET the referee's self-description: available starter decks, level range, request shapes, and the honest scope note (costs, power, counters, blockers, and battle steps are real; other card effects are not interpreted yet).
Run this
curl https://cambridgetcg.com/api/v1/play/practice
Expected response shape
{ "@kind": "practice_referee_description", "how": { "new_game": {...}, "move": {...} }, ... }What to do with it
Pick a starter_id and a level_id. Level 1 (Alvida) is gentle; level 10 (Kaido) plays at full aggression.
POST op:'new'. You get the full game object (keep it — you are its custodian), the opening log, and your first legal_actions: the official mulligan decision.
Run this
curl -X POST https://cambridgetcg.com/api/v1/play/practice -H 'Content-Type: application/json' -d '{"op":"new","starter_id":"st-15-red-newgate","level_id":1,"goes_first":"toss"}'Expected response shape
{ "game": {...}, "legal_actions": [ { "move": { "type": "mulligan", "redraw": false }, "label": "Keep your opening hand." }, ... ], ... }What to do with it
Choose one legal_actions[].move verbatim — it is already shaped for the next request.
POST op:'move' with the game you carry and your chosen move. The response carries the updated game, the new log lines (the story of what happened), and fresh legal_actions with damage previews on every attack. When the AI attacks you, legal_actions becomes your defense options: block, counter, or take the hit.
Run this
curl -X POST https://cambridgetcg.com/api/v1/play/practice -H 'Content-Type: application/json' -d '{"op":"move","game":<game>,"move":{"type":"end_turn"}}'Expected response shape
{ "game": {...}, "new_log": [...], "legal_actions": [...], "finished": false, "winner": null }What to do with it
Loop until finished:true. Read new_log as you go — the referee narrates every rule it applies, with Comprehensive Rules numbers in the research doc it links.
The referee stores nothing. Lose the game object, lose the game. Editing it only rearranges your own practice table — results have no standing anywhere, by design.
An illegal move returns HTTP 200 with a `rejected` object whose reason teaches the rule you broke, plus unchanged game state. Read it, pick from legal_actions, continue.
Every card's verbatim rules text rides along (with its copyright line — render it wherever you show the text) so you can plan, but [Trigger]/[On Play]-style effects do not fire. The scope note in every response says exactly what is real.