ChaosDraft API WikiOpenAPI v1

Practical API examples

Wiki home · Getting started · All 78 operations · Exact schemas

These recipes show what an application can build with the current API. Commands use the real API origin. Replace sample IDs with IDs returned by your own requests. An API key must stay on your server; never put it in browser code or a public repository. The examples below are deliberately split by current access: a normal customer key cannot call a first-party-only route, even though the route is documented here.

Goal Start with Current access
Build a grounded MTG chat ASK AI ask_ai
Show one card's cheapest stored purchase option Cards and prices card:purchase:read
Search cards, printings and sets Cards and prices First-party *
Look up rules, rulings, formats and legality Rules and legality First-party *
Parse, analyze, save and compare decks Decks First-party *
Discover programs, events and stores Events and stores First-party *

1. Check what your key can use

Set `CHAOSDRAFT_API_KEY` in your server's secret manager, then check ASK access. This read does not spend an AI message.

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/access' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY"

The response describes the key's status, scopes and allowance. It is not a DeckForge subscription lookup. A 401 means the key is missing, invalid, expired or revoked; a 403 means a route or field is outside its grant. Do not retry a denied request with a different path to bypass that restriction.

2. Build a two-turn chat

Send a question. Render `data.message.markdown` (safe Markdown with card markers) or `data.message.content` as the actual assistant reply. `data.answer.summary` is only a short summary. Store the returned `data.conversation.id` on your server for the next turn, along with the same end-user identity.

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/ask' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"question":"What does Llanowar Elves do?"}'

For a customer-owned key serving many people, add `X-End-User-Ref` with your own stable, opaque user ID on both requests. The server must choose this value; do not accept it from a browser request without checking the signed-in user.

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/ask' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H "X-End-User-Ref: $END_USER_REF" \
  -H 'Content-Type: application/json' \
  --data '{"question":"Would it fit my green Commander deck?","conversation_id":"<conversation UUID from first answer>"}'

Only an active customer-owned key may use that header. A missing header targets the key's default user and cannot read a named end user's chat. The answer also includes grounding, source information, card previews and tool trace for your optional detail panel. ASK AI explains the full response and conversation lifecycle.

3. Stream a chat response

`stream:true` uses server-sent events. Show `delta` as temporary progress. A `reset` clears provisional text. The `final` event carries the authoritative answer; replace the temporary text with its `data.message`. Treat an `error` event as failure even if the original HTTP status was 200.

curl -N --fail-with-body 'https://api.chaosdraft.com/v1/ai/ask' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  --data '{"question":"How does trample work?","stream":true}'

4. Ask about a deck or a nearby event

The deck travels with this request; it is not automatically stored in DeckForge or the API deck library. A deliberately short list is shown to explain the shape, not to claim it is format-legal. Supply the complete deck for a meaningful review.

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/ask' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"question":"How are my lands and curve?","format":"standard","deck":{"text":"Deck\n4 Llanowar Elves\n4 Opt\n12 Forest\n12 Island"}}'

For a nearby event, send a request-scoped location. The API uses it to search its stored listings; it is not saved as a profile location. Include an IANA time zone when local times matter.

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/ask' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"question":"Any Magic events near me this weekend?","location":{"city":"Seattle","region":"WA","country":"US"},"timezone":"America/Los_Angeles"}'

An unlisted event is not proof that no event exists. Check the response's coverage and source links. ASK can also take a Limited pool, a conversation file, or up to four image attachments; see ASK AI and the exact request schema.

5. Manage chats, files and feedback

List chats with an opaque cursor, fetch a chat with turn history, and page older turns using `before_turn`. Repeat the same end-user ref on every subject request.

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/conversations?limit=20' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY"
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/conversations/<conversation UUID>?turn_limit=20' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY"

Attach a deck file to an existing chat, then ask about `file_id` with the same `conversation_id`:

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/conversations/<conversation UUID>/files' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"kind":"deck","name":"My green deck","text":"Deck\n4 Llanowar Elves\n12 Forest"}'

Rate a saved assistant turn. The `turn` number comes from that conversation's turn list.

curl --fail-with-body -sS -X PUT \
  'https://api.chaosdraft.com/v1/ai/conversations/<conversation UUID>/turns/<turn number>/feedback' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"rating":"down","comment":"The card count was wrong."}'

The same family supports chat creation, renaming and deletion; file listing, reading and deletion; memory reads/edits/erasure; a live event stream; and customer-wide feedback export under the separate `ai:feedback:read` scope. Those exact methods and paths are in ASK AI and All endpoints.

Send a card photo or a Limited pool

For an image, build JSON on your server from a local JPEG, PNG or WebP file. This example reads `card.jpg` and sends one photo; the API accepts at most four, enforces size limits and strips metadata before model processing. Image use also depends on processor approval.

python3 - <<'PY' > image-request.json
import base64, json
from pathlib import Path
photo = base64.b64encode(Path('card.jpg').read_bytes()).decode('ascii')
print(json.dumps({'question': 'What card is in this photo?',
                  'attachments': [{'type': 'image', 'media_type': 'image/jpeg', 'data': photo}]}))
PY
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/ask' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H 'Content-Type: application/json' \
  --data-binary @image-request.json

Treat the photo as request input, not a verified card identity. Use the returned checked card mention and grounding status. Remove the temporary JSON when finished; it contains the image. To build from a Sealed pool, send `pool:{"text":"1 Card Name\n...","kind":"sealed"}` with your question. A follow-up in the same conversation can reuse that pool; send `pool:null` to end that pool context.

Keep multiple chat clients in sync

Open the subject's event stream in a long-lived server request. When it reports `turn.completed` or `turn.failed`, refetch that conversation; event IDs are a cue to refresh, not the answer body. Browser applications should use their own backend as the key holder.

curl -N 'https://api.chaosdraft.com/v1/ai/events' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H "X-End-User-Ref: $END_USER_REF"

Read memory or export customer feedback

`GET /v1/ai/memory` reads the subject's memory state. `PATCH` updates/removes item IDs from that result and `DELETE` erases all memory; do not assume memory is enabled for a key. The customer-wide feedback export needs a separate `ai:feedback:read` grant and deliberately has no `X-End-User-Ref` header:

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/memory' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  -H "X-End-User-Ref: $END_USER_REF"
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/ai/feedback?limit=100' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY"

6. Show a card's cheapest stored purchase option

This route needs `card:purchase:read`; `ask_ai` alone is insufficient. First obtain an Oracle ID from a permitted card result or ASK card mention. A stored quote may be absent; it is not a live checkout price.

curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/cards/<oracle UUID>/cheapest-purchase' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY"

Display price with currency, condition, finish and observation time. If the response includes a permitted buy URL, use that URL rather than constructing a Card Kingdom URL yourself; it can carry the customer's configured affiliate code. Image and product-link rights are separate source-policy checks.

7. Search cards and editions (first-party)

The following examples require a privileged first-party `*` key. A normal customer key cannot call them today. Card identity and printing identity are different: use an Oracle ID for gameplay identity and a printing ID for edition-specific art or price.

curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/cards?name=Llanowar%20Elves&limit=10' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"
curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/cards/named?exact=Llanowar%20Elves' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/cards/resolve' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"names":["Llanowar Elves","Opt"]}'

Use the returned Oracle ID with `/v1/cards/{oracle_id}`, `/printings`, or `/parts`; use an exact printing ID with `/v1/printings/{printing_id}` and `/v1/prices/printings/{printing_id}`. `/v1/cards/autocomplete?q=...` powers typeahead; `/v1/cards/by-identifier` and `/v1/printings/by-identifier` map external IDs. `/v1/sets`, `/v1/sets/{code}`, and `/v1/sets/{code}/cards` cover sets. `/v1/sources` and `/v1/status` expose attribution and source freshness. See Cards, sets and prices.

8. Verify a rule, ruling and format (first-party)

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/rules/search?q=trample&limit=10' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/rules/704.5' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"
curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/cards/<oracle UUID>/rulings?limit=10' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"
curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/formats/standard/banlist' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"

Rule text may be withheld while an identifier/version remains visible. Quote only text actually returned. Use a ruling's publication date for the ruling, and `as_of` plus coverage for date-specific format claims. The family also lists rule versions, the glossary, format definitions, eligible sets and governing events. Rules, formats and legality covers those paths.

9. Check card and deck legality (first-party)

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/legality/cards' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"format":"standard","cards":[{"name":"Llanowar Elves"}]}'
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/legality/decks' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"format":"standard","deck":{"text":"Deck\n4 Llanowar Elves\n12 Forest"}}'

The second list is intentionally incomplete and will not be a legal Standard deck. For a real decision send the full deck and inspect resolution, violations, warnings and coverage. An uncovered date or unresolved card is not a verified legal result.

10. Analyze and compare decks (first-party)

`parse` reads text without saving. `analyze` returns the full deterministic analysis; `/analyze/curve` and `/analyze/mana-base` focus on one part. `diff` compares two supplied states.

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/decks/analyze' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"deck":{"text":"Deck\n4 Llanowar Elves\n4 Opt\n12 Forest\n12 Island"},"format":"standard"}'
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/decks/diff' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"from":{"text":"Deck\n4 Llanowar Elves\n12 Forest"},"to":{"text":"Deck\n4 Llanowar Elves\n13 Forest"}}'

These short lists illustrate the request shape. For meaningful curve, mana, probability and legality output, send a complete list and examine analysis warnings. The Decks page explains optional pricing, incomplete data and stored deck versions.

11. Save a deck and add a version (first-party)

curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/decks' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"name":"Example green deck","format":"standard","deck":{"text":"Deck\n4 Llanowar Elves\n12 Forest"}}'
curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/decks/<returned deck UUID>/versions' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"deck":{"text":"Deck\n4 Llanowar Elves\n13 Forest"},"note":"Added a Forest"}'

The deck ID and version IDs come from the create/version responses. Read `/v1/decks/{id}` and `/versions/{version_id}`, analyze a saved version with `/analysis`, compare with `/diff?against=<other version UUID>`, and use PATCH/DELETE on the deck when appropriate. There is no list-all-decks route. These API-stored decks are separate from DeckForge's saved decks.

12. Find programs, events and stores (first-party)

curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/event-programs?upcoming=true&limit=10' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"
curl --fail-with-body -sS 'https://api.chaosdraft.com/v1/events/search' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"location":{"city":"Seattle","region":"WA","country":"US"},"radius_km":25,"limit":10}'
curl --fail-with-body -sS \
  'https://api.chaosdraft.com/v1/stores?city=Seattle&region=WA&country=US&limit=10' \
  -H "Authorization: Bearer $CHAOSDRAFT_FIRST_PARTY_KEY"

Use returned event and store IDs to fetch individual records or a store's events. The service reads stored observations rather than contacting an organizer live. Check coverage, freshness, time zone and source attribution before showing a date, fee or availability. See Events and stores.

13. Page results and handle errors

If a response includes an opaque next cursor, send it back with the same filters and key/end-user identity. Do not decode or synthesize it. The operation index shows which routes take `cursor`; others use `offset` or turn numbers. Example:

curl --fail-with-body -sS --get \
  'https://api.chaosdraft.com/v1/ai/conversations' \
  -H "Authorization: Bearer $CHAOSDRAFT_API_KEY" \
  --data-urlencode 'limit=20' \
  --data-urlencode 'cursor=<next cursor from previous response>'

On non-2xx responses, read `error.code`, `error.message` and `error.request_id`; keep the request ID for support. Honor `Retry-After` on 429. Do not retry 400/403 validation or permission failures as if they were temporary service failures. A successful transport status does not make an uncovered factual result complete; inspect coverage and warnings.