Sun Terminal · Developer reference

Rider–Waite Tarot developer reference

Complete HTTP v1 integration reference for the Sun Terminal Rider–Waite Tarot consultation operation.

Consultation operation

A live 78-card Rider–Waite divination instrument that returns card identities and orientations for interpretation by the caller.

POST https://sunterminal.net/api/v1/consult
Content-Type: application/json
Idempotency-Key: <fresh lowercase UUIDv7>

The operation is anonymous and requires no authentication. It accepts one JSON object of at most 8 KiB. Query parameters and unknown fields at every JSON level are rejected. It returns one final JSON response rather than a job or polling handle.

Generate a current UUIDv7

Generate a lowercase UUIDv7 immediately before the encounter. Its embedded issue time must be less than 24 hours old and no more than 5 minutes ahead of the server clock. Preserve the same key for every retry; after an uncertain commit, do not create a replacement retry key.

Use a maintained UUIDv7 implementation for your runtime or the mechanically checked Node example linked below. The example creates a current key at execution time; no fixed example key is reusable.

Request body

schema_version is sun-terminal.consult-request@1. instrument must be tarot.rider-waite at immutable version 1. structural_inputs is required; count defaults to 1 and ranges from 1 through 78. position_labels is optional and, when present, must contain exactly count values in the ordered generic sequence position-1 through position-N.

There is no accepted field for question text, a caller-selected production seed, meanings, interpretation, named spreads, caller-authored labels, locale, rendering or witness behavior.

Success response

HTTP 200 returns application/json with schema_version, encounter_id, final status, immutable instrument and manifest digest, raw_result, receipt and instrument_url. raw_result contains normalized structural inputs, ordered positions with card_id and upright or reversed orientation, the complete-permutation commitment and a raw-result hash.

The response contains identities and orientations, without card meanings, keywords, correspondences or reading prose. receipt.interpretations is empty. Cache-Control is no-store.

Canonicalization and safe replay

The request fingerprint covers the request schema, operation identity, immutable instrument and resolved manifest, normalized count, and normalized labels or null. Defaults are applied before hashing. JSON member order, JSON whitespace and the raw idempotency key do not enter the fingerprint.

Repeating the same canonical input and key returns the exact stored response bytes and consumes no new entropy. Reusing that key with changed canonical input returns HTTP 409 idempotency_conflict and does not draw. A successful response does not add a replay flag, so compare the returned bytes or encounter id when retrying.

Stable errors and retry handling

Every failure uses schema_version sun-terminal.error@1 and an error object containing code, message and retryable. Error bodies do not echo rejected values, request bodies, idempotency keys, credentials or receipts.

Retry-After is conditional. Its value is 1 only for encounter_recovery_required or idempotency_commit_unknown. It is absent for encounter_failed and other non-retryable errors.

HTTP 503 agent_door_unavailable
The agent consultation door is not enabled. Retry guidance: wait then retry the same request and key.
HTTP 409 encounter_failed
This committed encounter could not be completed and will not be redrawn under this idempotency key. Retry guidance: do not retry as the same encounter.
HTTP 409 encounter_recovery_required
The encounter is committed but not final. Retry the same request with the same idempotency key; no new draw will be created. Retry guidance: retry the same request and key. Response header: Retry-After: 1.
HTTP 503 idempotency_commit_unknown
The idempotency commit could not be confirmed. Retry only with the same idempotency key. Retry guidance: retry the same request and key. Response header: Retry-After: 1.
HTTP 409 idempotency_conflict
This idempotency key is already bound to different canonical input. Retry guidance: do not retry as the same encounter.
HTTP 409 idempotency_key_expired
This idempotency key is outside the retry window. Do not create a replacement retry key. Retry guidance: do not retry as the same encounter.
HTTP 404 instrument_not_found
The requested instrument is not available. Retry guidance: correct request before retrying.
HTTP 409 instrument_version_unavailable
The requested immutable instrument version is not available. Retry guidance: correct request before retrying.
HTTP 400 invalid_json
The request body must be valid JSON. Retry guidance: correct request before retrying.
HTTP 400 invalid_request
Content-Type must be application/json. Retry guidance: correct request before retrying.
HTTP 405 method_not_allowed
Use POST for one atomic consultation. Retry guidance: correct request before retrying. Response header: Allow: POST.
HTTP 413 payload_too_large
The consultation request must not exceed 8 KiB. Retry guidance: correct request before retrying.
HTTP 503 rate_limit_unavailable
Anonymous consultation is unavailable because its rate limit is not active. Retry guidance: wait then retry the same request and key.
HTTP 429 rate_limited
The anonymous consultation limit has been reached. Retry later with the same idempotency key. Retry guidance: wait then retry the same request and key. Response header: Retry-After: 60.
HTTP 503 service_unavailable
The consultation service is temporarily unavailable. Preserve the idempotency key and try again later. Retry guidance: wait then retry the same request and key.

Pending ownership and terminal failure

A newly acquired pending encounter has a 30-second ownership lease. Reaching the deadline only makes its row eligible for a later matching request with the same canonical input and idempotency key to conditionally record terminal failure; time passing alone does not run a background transition.

A failed encounter is terminal. It returns HTTP 409 encounter_failed with retryable set to false and no Retry-After header, and it will not be redrawn under that idempotency key. Sun Terminal does not create or recommend a replacement consultation.

A failed D1 row stores a failure timestamp and one of two bounded internal failure classifications through the existing 24-hour active idempotency window. It stores no exception name, exception message or subsystem-specific cause. The internal classifications are not public error codes.

Rate limit, retention and browser CORS

The anonymous limiter counts 10 attempts per 60 seconds per connecting IP at each Cloudflare location and runs before body parsing. It is permissive and location-local rather than exact global accounting. If the limiter is unavailable, the operation fails closed.

The active retry window is 24 hours. Hourly cleanup deletes expired active D1 rows; Cloudflare D1 Time Travel may retain recoverable database history after active deletion depending on platform plan and configuration.

The operation sends no Access-Control-Allow-* headers. Browser requests from another origin cannot complete the required preflight; same-origin and non-browser clients are unaffected.

An OPTIONS preflight receives HTTP 405 method_not_allowed with Allow: POST and no Access-Control-Allow-* response headers. Use a server-side client or a same-origin context rather than cross-origin browser JavaScript.

Public integration resources