MTGF

MTGF Public API v1

Version 1.0.0

Public REST API for MTGF — card discovery, deck building, and sharing. Everything is a plain REST endpoint returning JSON, so you can call it from scripts, apps, bots, or anything else that speaks HTTP.

Authentication

Generate an API key in your account settings and send it as a Bearer token:

Authorization: Bearer mtgf_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Endpoints with security: [{}, { bearerAuth: [] }] accept anonymous calls; endpoints with security: [{ bearerAuth: [] }] require a key. Card endpoints are public.

Rate limits

Limits are enforced within a 60-second rolling window:

Caller Requests / minute Key
Authenticated (API key) 120 per API key
Anonymous 30 per IP address

Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix seconds). Exceeding the limit returns HTTP 429 with a Retry-After header.

Pagination

List endpoints accept limit and offset query parameters. The default and max limit are per-endpoint (see each operation's documented defaults). offset + limit must be ≤ 10,000; requests exceeding that window return HTTP 400. For use cases that require paging deeper than 10,000 rows, narrow your filters or contact support — cursor pagination is on the roadmap for deep lists but is not yet available.

Response envelope

All successful responses use a standardized envelope. data contains the resource or list. meta is present on paginated endpoints and may include additional context-specific fields. Mutation endpoints that don't return a resource use { "data": { "success": true } }.

{
  "data": <T>,
  "meta": { "total": number, "limit": number, "offset": number, "hasMore": boolean }
}

Errors

All 4xx/5xx responses share a standard H3 error envelope. error is always true, which is how clients can distinguish failures from { data } success envelopes without inspecting the status code. Validation errors may include a data field with structured issue details. A stack field is present only in development and must not be consumed in production integrations.

{
  "error": true,
  "url": "/api/v1/decks/dk_missing",
  "statusCode": 404,
  "statusMessage": "Not Found",
  "message": "Deck not found"
}

Validation errors

All validation failures — malformed bodies, bad query params, unknown enum values — return HTTP 400 Bad Request. This API does not use 422 Unprocessable Entity.

Authorization and 404

For authenticated resource endpoints (e.g. a deck by ID), 404 is also returned when the resource exists but is owned by another user — ownership is never disclosed. Treat 404 as "not accessible" for resource-ownership cases.

Scope errors (403)

The one exception to the "no 403" rule above: when you present a valid API key that is simply missing a required scope for the endpoint, the API returns HTTP 403 Forbidden with a message naming the required scope. This is distinct from 401 (missing/invalid key) and 404 (resource not accessible). To recover, regenerate an API key with the required scope granted.

Card images and hotlinking

Card image URLs in responses (image_uris.*, coverImage, etc.) point to the Scryfall CDN. MTGF inherits Scryfall's image usage policy: you may hotlink images directly for display, but you must not re-host them at scale or rebuild a competing image catalog. For production integrations, cache responses and their URLs; do not fetch the same image URL on every render. See Scryfall's image guidelines for the canonical policy.

Nullable PATCH fields

For PATCH endpoints, omitting a field leaves it unchanged; passing null (where the field is nullable, e.g. coverCardId) explicitly clears it. Passing a value updates it. There is no separate "unset" sentinel.

Versioning & deprecation

This API is versioned in the URL (/api/v1). Breaking changes ship as a new major version under /api/v2; the previous version keeps working until formally sunset. Individual fields slated for removal are marked with x-deprecated: true in this spec and remain functional for at least 90 days before being removed. New fields, endpoints, and enum values are additive and are not considered breaking.

Idempotency

Selected mutation endpoints (currently POST /decks and POST /decks/{id}/cards/batch) accept an optional Idempotency-Key request header. The key is a client-generated string (typically a UUID, max 255 characters). When the same key and request body are sent again within 24 hours, the original response is replayed byte-for-byte and no new work is performed; responses to replays include Idempotent-Replay: true. Keys are scoped per endpoint path and per API key owner. Sending a previously used key with a different body is treated as a new request — consistent bodies are the caller's responsibility.

CORS

The API does not emit CORS headers (Access-Control-Allow-Origin and friends are not set). This is intentional: the API is designed for server-to-server integrations and same-origin browser calls (i.e. JavaScript running on the MTGF site itself). Cross-origin browser clients hosted on a different domain cannot call the API directly — the browser will block the response. If you are building a third-party browser app, proxy your requests through a backend you control and call the MTGF API from there. CORS support for first-party partner origins may be added later via an allowlist; reach out via support if you need it.

Request tracing

Every response includes an X-Request-Id header (UUID, or the value you supplied in the incoming X-Request-Id header if short enough). Include this value in support requests to speed up debugging.

Contact
MTGF Support
License
Proprietary
Terms
https://mtgf.net/terms

Servers

https://mtgf.net/api/v1Production

Security schemes

Name Type Description
bearerAuthhttp / bearerAPI key from your MTGF account settings

Tags

Cards

Read-only card catalog. Search, autocomplete, lookup by ID, find similar cards, and bulk-resolve print UUIDs. All endpoints in this group are public — no API key required.

Decks

Create, read, update, delete, fork, publish, import, and export decks. Most endpoints are scoped (require an API key with the matching `decks:*` scope).

Users

Read-only access to public user profiles and their published decks (lookup by handle and slug, list a user's decks, list forks of a published deck).

Account

Information about the API key holder — currently just `GET /me`, which returns the authenticated account and the granted scopes on the calling key.

cards

GET
/cards
Bearer auth required

Search cards

Search for Magic: The Gathering cards with filters

Parameters

Name In Type Description
any
search querystringCase-insensitive substring + fuzzy match against card name.
lang querystringCard language (ISO 639-1). Defaults to "en".
colors query"W" | "U" | "B" | "R" | "G"[]
type querystringCard type-category match (e.g. "creature", "instant", "sorcery"). Lowercased and compared against the card's type_category; not a substring search on the full type_line.
set querystringExact set code match (lowercase, e.g. "lea", "m21").
rarity query"common" | "uncommon" | "rare" | "mythic" | "special" | "bonus"Rarity filter. Exact match against the card's rarity.
cmc_min querynumberMinimum converted mana cost (inclusive).
cmc_max querynumberMaximum converted mana cost (inclusive).
power_min querynumberMinimum power (inclusive).
power_max querynumberMaximum power (inclusive).
toughness_min querynumberMinimum toughness (inclusive).
toughness_max querynumberMaximum toughness (inclusive).
keywords querystring[]
oracle_text querystringSubstring match against the card's oracle text (case-insensitive).
legal_in querystringRestrict to cards legal in the given format. Exact match against a format key in the card's legalities map. Uses the shared deck format vocabulary: standard, modern, legacy, vintage, pioneer, commander, brawl, pauper, historic, explorer, timeless, alchemy, penny, oathbreaker.
sort query"name" | "price" | "cmc" | "released" | "rarity"Sort column. Defaults to "name".
order query"asc" | "desc"Sort direction. Defaults to "asc".
unique querybooleanWhen true (default), collapses duplicate printings to a single row per card name.
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object[]
meta object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/cards/{id}
Bearer auth required

Get a card

Get a card by ID with all prints and rulings. Rulings are embedded in the response under rulings — there is no separate rulings endpoint.

Parameters

Name In Type Description
any
id *pathstring (uuid)Card ID — a Scryfall print UUID, not an oracle ID. Different printings of the same card have different IDs.

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/cards/{id}/similar
Bearer auth required

Find similar cards

Find cards similar to a given card using AI embeddings

Parameters

Name In Type Description
any
id *pathstring (uuid)Card ID — a Scryfall print UUID, not an oracle ID. Different printings of the same card have different IDs.
limit queryinteger

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object[]
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/cards/autocomplete
Bearer auth required

Autocomplete card names

Autocomplete card names

Parameters

Name In Type Description
any
q *querystring
legal_in querystring

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object[]
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
POST
/cards/lookup
Bearer auth required

Batch look up cards by id

Resolve up to 200 Scryfall print UUIDs in a single request. Designed for hydrating PublishedDeck.cards[] or any list of card references without making one round-trip per card. Unknown ids are returned in missing.

Parameters

Name In Type Description
any

Request body

Field Type Description
ids *string (uuid)[]

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/cards/random
Bearer auth required

Get random cards

Return N random cards (1-10). Not paginated — each call re-rolls a fresh random set. The response envelope contains data only; there is no meta object (no total, offset, or hasMore).

Parameters

Name In Type Description
any
count queryinteger

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object[]
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.

decks

GET
/decks
Bearer auth required

List decks

List your decks with optional filters and sorting.

Parameters

Name In Type Description
any
search querystringCase-insensitive substring match against deck name.
format querystringFilter by deck format identifier. Free-form format identifier. Not enforced as an enum — custom and future formats are accepted. The canonical vocabulary (shared between deck `format` and card `legal_in`) is: standard, modern, legacy, vintage, pioneer, commander, brawl, pauper, historic, explorer, timeless, alchemy, penny, oathbreaker.
sort query"updated" | "created" | "name"Sort column. Defaults to "updated" (most recently updated first).
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object[]
meta object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
POST
/decks
Bearer auth required

Create deck

Create a new deck. Send a unique Idempotency-Key header (client-generated UUID, max 255 chars) to safely retry on network failures without creating duplicates; the original response is replayed for 24h when the same key and body are resent.

Parameters

Name In Type Description
any
Idempotency-Key headerstringOptional client-generated key (typically a UUID, max 255 chars). When the same key and body are resent within 24 hours, the original response is replayed byte-for-byte and `Idempotent-Replay: true` is returned.

Request body

Field Type Description
name *stringDeck name (1-200 characters).
description stringOptional free-form description (up to 2000 characters).
format stringOptional deck format identifier (up to 50 characters). Free-form format identifier. Not enforced as an enum — custom and future formats are accepted. The canonical vocabulary (shared between deck `format` and card `legal_in`) is: standard, modern, legacy, vintage, pioneer, commander, brawl, pauper, historic, explorer, timeless, alchemy, penny, oathbreaker.

Responses

201
Resource created. Body is the standard `{ data }` envelope describing the new resource.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
DELETE
/decks/{id}
Bearer auth required

Delete a deck

Delete a deck

Parameters

Name In Type Description
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/decks/{id}
Bearer auth required

Get a deck

Get a deck with its cards

Parameters

Name In Type Description
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
PATCH
/decks/{id}
Bearer auth required

Update deck

Update deck metadata

Parameters

Name In Type Description
any
any

Request body

Field Type Description
name stringNew deck name (1-200 characters). Omit to leave unchanged.
description stringNew description (up to 2000 characters). Omit to leave unchanged.
format stringNew deck format identifier (up to 50 characters). Omit to leave unchanged. Free-form format identifier. Not enforced as an enum — custom and future formats are accepted. The canonical vocabulary (shared between deck `format` and card `legal_in`) is: standard, modern, legacy, vintage, pioneer, commander, brawl, pauper, historic, explorer, timeless, alchemy, penny, oathbreaker.
coverCardId string | nullScryfall print UUID to use as the deck cover image. Pass null to clear, omit to leave unchanged.

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
POST
/decks/{id}/cards
Bearer auth required

Add card to deck

Add a card to a deck. Upserts on (deckId, cardId, board) — if the card already exists on the target board, its quantity is incremented by the supplied amount (capped at 99). To change quantity without adding, send the desired delta; to remove, use DELETE /decks/{id}/cards/{cardId}. There is no PATCH endpoint for individual cards. Returns the full deck detail so clients do not need a follow-up GET.

Status code: 201 Created when a new card entry is inserted on the board; 200 OK when an existing entry has its quantity incremented. The response body is identical in both cases (full deck detail).

Parameters

Name In Type Description
any
any

Request body

Field Type Description
cardId *stringScryfall print UUID of the card to add.
quantity *integerQuantity to add. Defaults to 1 when omitted. Existing cards on the same board have their quantity incremented (capped at 99).
board *"main" | "sideboard" | "maybeboard" | "commander"Target board. Defaults to "main" when omitted.
posX numberOptional X coordinate for placing the card on the canvas deck builder.
posY numberOptional Y coordinate for placing the card on the canvas deck builder.

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
201
A new card entry was inserted on the target board. Body is the standard `{ data }` envelope with the full deck detail.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
DELETE
/decks/{id}/cards/{cardId}
Bearer auth required

Remove card from deck

Remove a card from a deck on a specific board.

Parameters

Name In Type Description
any
any
any
board *query"main" | "sideboard" | "maybeboard" | "commander"

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
POST
/decks/{id}/cards/batch
Bearer auth required

Batch deck card mutations

Apply a batch of add/remove/update-quantity mutations to a deck in a single atomic ClickHouse write. Prefer this over individual POST/DELETE calls when making more than a few changes (e.g. importing, bulk editing).

Atomicity: the batch is all-or-nothing. If any mutation is invalid (unknown cardId, malformed body, etc.) the entire request fails with 400 and no mutations are applied. Partial success is not possible — successful mutations are reflected in the added/removed/updated counters in the response, while failures surface as a normal error envelope ({ error: true, statusCode: 400, message: ..., data: { issues: [...] } }). There is no per-mutation failed[] channel.

Send a unique Idempotency-Key header (client-generated UUID, max 255 chars) to safely retry on network failures without re-applying mutations; the original response is replayed for 24h when the same key and body are resent.

Parameters

Name In Type Description
any
Idempotency-Key headerstringOptional client-generated key (typically a UUID, max 255 chars). When the same key and body are resent within 24 hours, the original response is replayed byte-for-byte and `Idempotent-Replay: true` is returned.
any

Request body

Field Type Description
mutations *object | object | object[]Ordered list of deck-card mutations to apply atomically (1-100 per batch).

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/decks/{id}/export
Bearer auth required

Export a deck

Export a deck as text. Defaults to a JSON envelope ({ data: { text, name, format } }) suitable for programmatic use. Send Accept: text/plain to receive the raw decklist as the response body — convenient for shell pipelines like curl ... | pbcopy.

Parameters

Name In Type Description
any
any
format query"mtga" | "mtgo" | "plain"

Responses

200
JSON envelope by default; when the request includes `Accept: text/plain`, the body is the raw decklist text instead.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
POST
/decks/{id}/fork
Bearer auth required

Fork deck

Fork a deck. The source must be either published (has a slug) or owned by the API key holder. Returns the new deck ID.

Parameters

Name In Type Description
any
any

Request body

Field Type Description
name stringOptional name for the new forked deck (1-200 characters). Defaults to the source deck name with a suffix when omitted.

Responses

201
Resource created. Body is the standard `{ data }` envelope describing the new resource.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
POST
/decks/{id}/import
Bearer auth required

Import deck

Import cards into a deck from decklist text

Parameters

Name In Type Description
any
any

Request body

Field Type Description
text *stringRaw decklist text to parse and import (1-50000 characters).
board *"main" | "sideboard" | "maybeboard" | "commander"Board to import cards into. Defaults to "main" when omitted.

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
POST
/decks/{id}/publish
Bearer auth required

Publish deck

Publish or unpublish a deck. Published decks are accessible at /u/{handle}/d/{slug}.

Parameters

Name In Type Description
any
any

Request body

Field Type Description
publish *booleanTrue to publish the deck publicly, false to unpublish and make it private again.

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.

me

GET
/me
Bearer auth required

Get current account info

Returns the account tied to the current API key along with its granted scopes.

Parameters

Name In Type Description
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
401
Unauthorized — no API key was sent, or the supplied bearer token is unknown, expired, or revoked. Generate a new key in account settings and resend.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
403
Forbidden — the API key is valid but does not carry the scope this endpoint requires. Issue a new key with the missing scope (named in `message`) granted.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.

users

GET
/users/{handle}
Bearer auth required

Get public user profile

Get a public user profile by handle

Parameters

Name In Type Description
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/users/{handle}/d/{slug}
Bearer auth required

Get published deck

Get a published deck by handle and slug

Parameters

Name In Type Description
any
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/users/{handle}/d/{slug}/forks
Bearer auth required

List deck forks

List public forks of a deck

Parameters

Name In Type Description
any
any
any
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object[]
meta object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
GET
/users/{handle}/decks
Bearer auth required

List user decks

Get a public user's listed decks

Parameters

Name In Type Description
any
any
any
any

Responses

200
Successful response. Body is the standard `{ data }` envelope.
Field Type Description
data *object[]
meta object
400
Bad request — the body, query, or headers failed validation. The `data.issues` array lists each Zod issue (path + message). Fix the input and retry.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
404
Not found — the resource does not exist, or it exists but is owned by another user (ownership is never disclosed). Treat both cases as "not accessible".
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.
429
Rate limit exceeded — too many requests in the current 60-second window. Honor the `Retry-After` header before retrying. See the rate-limit table in the spec intro.
Field Type Description
error *trueAlways `true` on error responses. Use this to distinguish error envelopes from `{ data }` success envelopes.
url *stringFull URL of the request that produced this error (includes protocol, host, and path).
statusCode *integerHTTP status code of the error (mirrors the response status line).
statusMessage *stringShort HTTP reason phrase for the status code (e.g. "Not Found", "Invalid request body").
message *stringHuman-readable explanation of what went wrong. Safe to surface to end users.
data object | objectOptional structured error payload. For validation failures (HTTP 400) this conforms to `ValidationErrorData` — see that schema for the per-issue shape.
stack string[]Stack trace frames. Present only in development builds; must not be consumed in production integrations.