Skip to main content

External developer API

The developer API gives external applications read-only access to published events, the public card catalogue, and progression standings. It suits campus event viewers, card guides, and backend integrations.

A developer key grants access to these resources. It does not grant player or Author permissions, reveal private collections or battles, or allow gameplay writes. Use the API reference for the interactive OpenAPI reference, exact schemas, and local API setup.

Get and protect a key​

Sign in and open Account settings → Developer API access. Give each key an application name so you can identify and revoke it later. An active account can have up to 5 active keys.

The complete credential appears only when creation succeeds. Save it then; later responses show metadata and a non-secret prefix. Keep the key in a server-side environment variable or secret store, outside source control, screenshots, URLs, and public frontend bundles.

Revoking a key blocks subsequent requests. Keys also stop working when the owning account becomes unavailable, including when account deletion begins. Revoked keys no longer count towards the active-key limit.

Authenticate a resource request​

Send the complete credential in X-API-Key:

X-API-Key: <api-key>

For a local API instance:

curl \
-H "X-API-Key: $WITS_WORLD_API_KEY" \
"http://127.0.0.1:3000/api/v1/developer/cards"

External resource routes use this header. Key-management routes use an Auth0 bearer token instead. A bearer token does not replace the developer key on external reads, and a developer key cannot authenticate player or Author routes.

Invalid, missing, revoked, and unavailable-account credentials all return 401 UNAUTHORIZED, without revealing whether a particular key exists.

Published events​

RouteResponse
GET /api/v1/developer/events{ events, pagination, requestId }.
GET /api/v1/developer/events/:eventId{ event, requestId }.

Events contain eventId, title, description, latitude, longitude, radiusMetres, startsAt, endsAt, and availability. Availability is active, upcoming, or ended. Locations and times reflect the event's current effective placement and schedule; published data can change between requests.

The list accepts page (default 1) and pageSize (default 50, maximum 100). It follows the same published discovery boundary as the player application. Questions, accepted answers, player attempts, and eligibility evidence are excluded. Reading an event through this API does not record a player event view.

Public card catalogue​

RouteResponse
GET /api/v1/developer/cards{ cards, requestId } containing the catalogue without pagination.
GET /api/v1/developer/cards/:cardDefinitionId{ card, requestId }.

Only active, published ordinary card definitions are returned. Each card contains its definition ID, name, category, affinity, rarity, description, artwork fields, hp, power, and deckPointCost. Values that do not apply can be null.

Evolution fields are evolvesFromCardDefinitionId and evolutionCopiesRequired. moves contains position, name, moveType, powerCost, and rulesText; effects contains position and rulesText. These are public card descriptions, rather than private execution configuration or player-owned copies.

Progression standings​

GET /api/v1/developer/leaderboard?period=all_time&page=1&pageSize=20
GET /api/v1/developer/leaderboard?period=monthly&month=2026-10&page=1&pageSize=20

The response is { period, month, entries, pagination, requestId }. Entries contain only playerName, points, and rank. This is the progression-points leaderboard; ranked PvP ratings use the separate ranked API.

period defaults to all_time, with month: null in the response. For monthly, send month in YYYY-MM format. Omit month for all-time requests. page defaults to 1 and pageSize to 20, with a maximum of 100.

Streaks, activity records, account identifiers, locations, and private gameplay history are excluded. See Progression rules for the meaning of points and monthly standings.

Pagination and responses​

Successful resource reads return 200. IDs in detail routes are UUIDs. Event and leaderboard pages include:

{
"page": 1,
"pageSize": 20,
"totalItems": 0,
"totalPages": 0
}

page is an integer from 1 to 10,000 and pageSize from 1 to 100. A page beyond the available results returns an empty collection. Responses are current reads, rather than a frozen multi-page snapshot, so totals and entries can change between requests. Extra query parameters are rejected on paginated routes.

Manage keys through HTTP​

These operations require Authorization: Bearer <access-token> for an active account. They manage only that account's keys.

MethodRouteRequest and response
GET/api/v1/developer/keys200 with { keys, activeKeyLimit, requestId }.
POST/api/v1/developer/keysSend { name }; 201 returns { key, apiKey, requestId }.
DELETE/api/v1/developer/keys/:keyId200 returns { key, requestId } after revocation.

A name must contain non-whitespace text and be at most 80 characters; it is trimmed before saving. Key metadata contains id, name, keyPrefix, createdAt, lastUsedAt, revokedAt, and status: active|revoked. Usage time is approximate and can be null. Creation returns Cache-Control: no-store.

Revoking an already-revoked owned key is safe. Creation has no idempotency key: if its response is lost, list your keys and revoke the uncertain new key before creating a replacement. The secret cannot be recovered from a later list.

Limits and recovery​

External reads have a quota per validated key. Key creation and revocation have separate account quotas. The rate limits guide defines the current defaults, headers, and temporary-service behaviour; it also explains why revocation remains available when rate protection is unavailable.

Errors use the standard API format. Keep the requestId when reporting a failure.

ResponseCaller action
400 VALIDATION_ERRORCheck parameter types, UUIDs, pagination bounds, and period/month combinations.
401 UNAUTHORIZEDCheck the credential required by this route and whether the key is still active.
403 ACCOUNT_UNAVAILABLEKey management is unavailable for this account.
404 NOT_FOUNDThe public resource or owned key is unavailable.
409 DEVELOPER_API_KEY_LIMIT_REACHEDRevoke an existing key before creating another.
429 RATE_LIMITEDWait for Retry-After before retrying.
503 RATE_LIMIT_UNAVAILABLEDelay before retrying key creation; no new key was issued by this rejection.

Read requests can be retried after transient connection or server failures. Follow the creation recovery steps above when a write's outcome is uncertain.

Browser integrations​

Use a backend to call the developer API on behalf of a public frontend, keeping the reusable key on the server. Arbitrary cross-origin browser requests are not supported by the API's CORS policy. CORS does not restrict direct HTTP clients such as backend services, Postman, or curl.

The interactive reference is served by the API and supports developer-key authorisation. For storage and account lifecycle details, see key storage and account retention.

AI declaration​

Rewritten with assistance from Codex[GPT-6], using developer routes, public response schemas, and key-management behaviour. Earlier documentation used ChatGPT-Web[GPT-5.6 Sol].