# Tarot API, what to build and how to call it

> Ship a daily tarot widget, a yes-no oracle, or a full Celtic Cross reader in under 20 minutes. Card imagery included.

Tarot is the highest-frequency divination surface Roxy ships. `/tarot/cards` is the highest per-endpoint call count in the catalog because every tarot app fetches the deck once and caches it. The daily card drives notifications, the three-card spread is the entry reading, Celtic Cross is the premium upsell, and yes-no is the highest-converting micro-feature on any tarot surface.

## What you can build

- Daily-draw tarot widgets for wellness and lifestyle apps
- Yes-no impulse features for dating and decision apps
- Full Celtic Cross reading apps with 10-position layouts
- Tarot chatbots that pick the right spread per question
- Card browsers with upright and reversed meanings

## Prerequisites

1. A Roxy API key. Get one on the [pricing page](/pricing).
2. A seed string if you want deterministic per-user results.

## Install


### npm
```bash
npm install @roxyapi/sdk
```

### Python
```bash
pip install roxy-sdk
```

### PHP
```bash
composer require roxyapi/sdk
```

Set the API key once at SDK construction. Detailed setup in [SDK install + usage](/docs/sdk).

## Call the endpoint

The #1 tarot call is the daily card. Seed it with a user ID and the same user gets the same card all day long (great for push notifications). Pick a language.


### curl
```bash
curl -X POST https://roxyapi.com/api/v2/tarot/daily \
  -H "X-API-Key: $ROXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"seed": "user-42"}'
```

### TypeScript SDK
```typescript
import { createRoxy } from '@roxyapi/sdk';

const roxy = createRoxy(process.env.ROXY_API_KEY!);

const { data } = await roxy.tarot.getDailyCard({
  body: { seed: 'user-42' },
});

console.log(data.card.name);     // "The Star"
console.log(data.card.imageUrl);
console.log(data.dailyMessage);
```

### Python SDK
```python
import os
from roxy_sdk import create_roxy

roxy = create_roxy(os.environ['ROXY_API_KEY'])

card = roxy.tarot.get_daily_card(seed='user-42')
print(card['card']['name'])
print(card['card']['imageUrl'])
print(card['dailyMessage'])
```

### PHP SDK
```php
<?php

use function RoxyAPI\Sdk\createRoxy;

$roxy = createRoxy(getenv('ROXY_API_KEY'));

$card = $roxy->tarot->getDailyCard(seed: 'user-42');
echo $card['card']['name'];
echo $card['card']['imageUrl'];
echo $card['dailyMessage'];
```

### MCP
```bash
claude mcp add-json --scope user roxy-tarot '{"type":"http","url":"https://roxyapi.com/mcp/tarot","headers":{"X-API-Key":"YOUR_KEY"}}'
```

Then ask Claude, "draw a daily tarot card for user 42." The agent returns the card name, keywords, and interpretation. Full setup for Cursor, Claude Desktop, Antigravity, and other clients: [MCP guide](/docs/mcp).

The response:

```json
{
  "date": "2026-04-23",
  "seed": "user-42",
  "card": {
    "id": "the-star",
    "name": "The Star",
    "arcana": "major",
    "number": 17,
    "position": "upright",
    "reversed": false,
    "keywords": ["Hope", "faith", "renewal"],
    "meaning": "A welcome reprieve after upheaval.",
    "imageUrl": "https://roxyapi.com/img/tarot/major/star.jpg"
  },
  "dailyMessage": "Your card for today, The Star..."
}
```

## Render the result

Skip building the render layer: `RoxyTarotCard` from [@roxyapi/ui](/docs/ui) renders the imagery, name, daily message, keywords, and a click-to-flip between upright and reversed. Fetch on your server so the key never reaches the browser, then pass the unwrapped `data` to the component. Prefer your own design? The response is plain JSON, render it however you like.

```tsx
'use client';
import { RoxyTarotCard } from '@roxyapi/ui-react';
import type { PostTarotDailyResponse } from '@roxyapi/sdk';

export function DailyCard({ data }: { data: PostTarotDailyResponse }) {
  return <RoxyTarotCard data={data} />;
}
```

The `data` you pass is the unwrapped SDK response, not the full `{ data, error }` envelope. For multi-card readings, use `RoxyTarotSpread` instead (see below).

## Ship the rest

### Three-card spread, the entry reading

[`POST /tarot/spreads/three-card`](/api-reference#tag/tarot/POST/tarot/spreads/three-card) returns past, present, future with per-position interpretation plus a top-level `summary`.

```bash
curl -X POST https://roxyapi.com/api/v2/tarot/spreads/three-card \
  -H "X-API-Key: $ROXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"question": "What should I focus on this month?"}'
```

Render any spread with `RoxyTarotSpread` from [@roxyapi/ui](/docs/ui). It lays out the positions, card imagery, per-position interpretation, and the top-level summary. Set the `spread` prop to match the endpoint (`three-card`, `celtic-cross`, `love`, `yes-no`, or `draw`).

```tsx
'use client';
import { RoxyTarotSpread } from '@roxyapi/ui-react';
import type { PostTarotSpreadsThreeCardResponse } from '@roxyapi/sdk';

export function ThreeCardSpread({ data }: { data: PostTarotSpreadsThreeCardResponse }) {
  return <RoxyTarotSpread data={data} spread="three-card" />;
}
```

### Celtic Cross, the premium reading

[`POST /tarot/spreads/celtic-cross`](/api-reference#tag/tarot/POST/tarot/spreads/celtic-cross) returns 10 positions (significator, cross, foundation, past, possible, near future, self, environment, hopes and fears, final outcome) with interpretation per position and a synthesized `summary`. This is the professional-reader spread.

### Yes-no, the highest-converting impulse feature

[`POST /tarot/yes-no`](/api-reference#tag/tarot/POST/tarot/yes-no) returns `Yes`, `No`, or `Maybe` with a strength indicator, the supporting card, and interpretation. Zero-config, highest conversion-to-first-call on any tarot surface.

### Love spread, the couples app bolt-on

[`POST /tarot/spreads/love`](/api-reference#tag/tarot/POST/tarot/spreads/love) returns a relationship-focused spread with positions and a top-level `summary`.

### Custom draws

[`POST /tarot/draw`](/api-reference#tag/tarot/POST/tarot/draw) takes `count` (1 to 78), optional `seed`, optional `allowReversals` (default true), optional `allowDuplicates` (default false). Every custom spread builds on this.

### The full 78-card catalog

[`GET /tarot/cards`](/api-reference#tag/tarot/GET/tarot/cards) returns the deck summary. [`GET /tarot/cards/{id}`](/api-reference#tag/tarot/GET/tarot/cards/{id}) returns the full card detail with upright, reversed, keywords, imagery, and meanings by life area. Fetch the catalog once, cache it, show card browsers without round-trips.

See the full list at the [Tarot API reference](/api-reference#tag/tarot).

## Ready-made starter

The [/starters/tarot-starter-app](/starters/tarot-starter-app) starter ships a working Tarot app you can clone, white-label, and deploy in 30 minutes. MIT licensed. For the render layer, drop in `<roxy-tarot-spread>` from [@roxyapi/ui](/docs/ui).

## Gotchas

- **`allowReversals: false` means no reversed cards, period.** It is a config flag, not a cosmic statement. Same with `allowDuplicates`.
- **Seed plus date is deterministic.** Same `(seed, date)` always returns the same card. This is by design for push-notification consistency. Do not describe it as "cached" or retry when the response looks familiar.
- **The response has `dailyMessage`, not `interpretation` at the top level.** Dig into `card.meaning` for the card-level meaning.
- **Card IDs are kebab-case.** `the-star`, `three-of-wands`, `knight-of-cups`. Use these in `/tarot/cards/{id}`.
- **Image URLs are absolute.** `imageUrl` is the full CDN URL, no prefixing needed.

## What to build next

The [tarot reading app tutorial](/docs/tutorials/tarot-app) builds a daily-card plus three-card-spread app in 30 minutes. For conversational tarot, the [AI chatbot tutorial](/docs/tutorials/ai-chatbot) shows MCP wiring. For typed calls, the [SDK guide](/docs/sdk) covers all spreads.
