---
name: set-api
title: Set World API
description: Procedurally generate fantasy RPG characters, items, equipment sets, rarity scores, orb prices, derived attributes, and trait impacts. Stateless JSON over HTTP GET, CORS open. Single discovery doc at /api/spec; this skill teaches the common usage patterns and keeps the canonical examples in one place.
homepage: https://set.world
spec: https://set.world/api/spec
license: MIT
version: 1
methods: [GET]
auth: none
cors: open
content_type: application/json
canonical_paths:
  - https://set.world/skill
  - https://set.world/skill.md
  - https://set.world/.well-known/skill
  - https://set.world/.well-known/skill.md
  - https://set.world/llms.txt
  - https://set.world/api/skill
---

# Set World API

Set is a fantasy role-playing world. Every generator (item, character, equipment set), every economy primitive (rarity, crafting, stat boost, monster drops), and every derived attribute is exposed as a stateless JSON endpoint. There is no auth, no session, no client SDK — just `fetch` or `curl` over HTTPS.

This skill is the human-and-agent-readable guide. The machine-readable surface map (every endpoint, query params, summary, and a two-line `scenario`) lives at `GET /api/spec`. When in doubt, fetch `/api/spec` first — it is the single source of truth and never drifts from this page.

## Conventions

- **Method**: `GET` only. Body-less.
- **Encoding**: JSON in, JSON out. Successful responses do not wrap (they return the payload directly).
- **Errors**: a uniform envelope `{ error: { code, message, field? } }`. `400` for validation, `501` for parked surfaces.
- **CORS**: open for `GET`, `POST`, `OPTIONS` from any origin.
- **Statelessness**: items are reconstructable from their roll vector; characters are the only persisted entity (encrypted blob in Postgres).
- **Stat order**: when an endpoint takes `stats=`, the order is fixed: `strength, dexterity, intelligence, wisdom, agility, vitality, perception, resolve, luck` (9 dash-joined integers). Always confirm via `GET /api/stats`.
- **Primary stats**: only 5 of the 9 stats — `strength, dexterity, agility, intelligence, vitality` — power the derived-attribute formulas. The other 4 (`wisdom, perception, resolve, luck`) are still rolled, traited, and displayed, but they don't directly compute derived attributes; that keeps the formula stable when stats are added or renamed.
- **Slot order**: equipment iteration uses `EQUIPMENT_SLOT_ORDER` from `/api/slots`.
- **Tier scale**: rarity tiers run T1–T7 (Common, Uncommon, Rare, Epic, Legendary, Mythic, Godly). Definitions and measured shares: `GET /api/rarity/tiers`.

## Discovery

Start with `GET /api/spec`. It returns `{ version, endpoints: [{ method, path, query?, summary, scenario: { use, returns }, example? }] }` — every endpoint with the same two-line "Use this when … / Returns …" copy a human reads on the home page.

```sh
curl https://set.world/api/spec
```

Supplementary tables that an agent typically needs once before composing other calls:

| Endpoint | Why |
| --- | --- |
| `/api/stats` | Canonical stat order and `[min, max]` bounds before posting `stats=` anywhere. |
| `/api/slots` | Slot list, per-slot capacity (hand and finger hold two), and the derived-attribute domain each slot influences. |
| `/api/drop/classes` | Encounter classes (`trash`, `veteran`, `elite`, `boss`, `world-boss`) and their drop multipliers (1, 3, 10, 50, 250). |
| `/api/rarity/tiers` | T1–T7 cutoffs and the §2 measured shares (T6 ≈ 0.4%, T7 unobserved at 200k samples). |
| `/api/attributes/spec` | Formula behind every derived attribute so a client can recompute locally. |

## Generators

### Roll a single item

```sh
curl https://set.world/api/roll/item
```

Returns a fresh item enriched with `score, scoreTier, tier, tierName, orbValue, material: { name, tier, tierName, floored }`, `affects` (the slot's derived-attribute domain), and a one-row `breakdown` matching the per-slot shape from `/api/roll/set`. The URL form `/roll/item` (no `/api`) renders the same item with the full weighted-table visualization and a permalink encoding the 19-number roll vector.

### Roll a full equipment set

```sh
curl https://set.world/api/roll/set
```

Returns `{ equipment, orbValue, orbBreakdown }`. `orbBreakdown` walks `EQUIPMENT_SLOT_ORDER` and emits one row per slot with `affects` and the items inside.

### Roll a character

```sh
curl https://set.world/api/roll/character
```

Returns base `stats`, `modifiedStats` (base reconciled with trait deltas, clamped to `[8, 24]`), `equipment` (enriched), `equipmentOrbValue`, `equipmentOrbBreakdown`, `traits` (advantages/disadvantages each carry their FNV-1a-derived `impact`), and the twenty derived `attributes`.

## Rarity

### Score a known item

```sh
curl 'https://set.world/api/rarity?indexes=0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18'
```

Pass either `indexes=` (preferred — the index-vector form persisted in URLs) or `rolls=` (the raw 19-number roll vector). Returns `score, scoreTier, tier, probability, orbValue, material: { name, tier, tierName, floored }`, and a `breakdown[]` of per-factor `−log10(p)` contributions sorted descending. `tier` is floored by the rolled material's tier; `scoreTier` exposes the unfloored joint-score tier so both signals stay inspectable.

### Tier definitions and shares

```sh
curl https://set.world/api/rarity/tiers
```

## Economy: orbs

The whole economy is denominated in a single currency (orbs). Every cost is precomputed and verifiable with the included Node scripts (`scripts/test-*.js`).

### Crafting (rejection-sample to a target tier)

```sh
curl 'https://set.world/api/craft?tier=5'
curl 'https://set.world/api/craft/cost?tier=5'   # up-front price + budget
```

`craftCost(T) = 5^(T-1)` → `1, 5, 25, 125, 625, 3125, 15625` orbs for T1..T7. The server rejection-samples until the *floored* tier hits or the rejection budget (`min(1_000_000, 100 × craftCost(T))`) runs out (`capped: true` is the honest answer at T7 with current weights).

### Best-of-N lottery

```sh
curl 'https://set.world/api/craft?orbs=125'
```

Returns the single highest-scoring item across `N` independent rolls plus `rolls` (the actual `N`) and a `rollsExpected` percentile band keyed off the §3.1.2 measured curve. The curve plateaus at T6.

### Stat boost

```sh
curl 'https://set.world/api/boost/cost?from=14&to=18'
```

`boostCostStep(s) = (s-7)^3` for `8 ≤ s ≤ 20`, then `4096 / 8192 / 32768` for the perfect wall steps `21/22/23`. Total `8 → 24 = 53,337` orbs.

### Monster drops

```sh
curl 'https://set.world/api/drop?stats=12-14-10-11-13-16-12-14-11&class=elite'
```

`baseDrop = round((avgStat - 6)^2 / 4)` × encounter-class multiplier × `uniform(0.75, 1.25)` variance. Optional `override=` and `seed=` parameters are documented in `/api/spec`.

## Traits

```sh
curl 'https://set.world/api/traits/impact?name=Iron%20Will&kind=advantage'
curl 'https://set.world/api/traits/impacts?kind=advantage'   # bulk pre-scored map
```

Every trait name hashes (FNV-1a 32-bit, offset basis `0x811c9dc5`, prime `0x01000193`, UTF-8 NFC) to a deterministic `{primary, primaryDelta, secondary?, secondaryDelta?, tier}`. Tiers 1–4 distribute 60/25/12/3. Magnitude tables: advantages `+5/+10/+15/+25%` primary; disadvantages `-8/-15/-22/-35%` primary.

## Derived attributes

```sh
curl 'https://set.world/api/attributes?stats=14-12-10-11-13-16-12-14-11'
curl https://set.world/api/attributes/spec
```

Twenty-three derived attributes — max health, stamina, physical/magical/action damage, six damage-reduction/resistance/dodge channels, six speed channels, carry capacity, jump height, vision range, crit chance, plus the three combat-utility channels `clarity` (anti-dodge accuracy), `initiative` (cooldown rate), and `reflexes` (counter to surprise hits) — each computed as `base + primaryCoef × (primary - 8) + secondaryCoef × (secondary - 8)` after the 5 primary stats are clamped to `[8, 24]`. Every primary and secondary in the formula table lives in `{strength, dexterity, agility, intelligence, vitality}`, so adding or renaming a non-primary stat can never break the derivation. `/api/attributes/spec` returns the full formula table.

## Recipes

### Build a complete level-1 character

```sh
curl https://set.world/api/roll/character
```

Single call: 9 base stats, modifiedStats, traits with impacts, full equipment, orb-equivalent value of the loadout, twenty-three derived attributes.

### Price a fight

```sh
curl 'https://set.world/api/drop/classes'
curl 'https://set.world/api/drop?stats=...&class=boss'
```

### Craft up to legendary

```sh
curl 'https://set.world/api/craft/cost?tier=5'   # → 625 orbs
curl 'https://set.world/api/craft?tier=5'        # → returns the legendary item
```

### Validate a third-party item

A consumer that tracks items by index vector can re-derive everything from the indexes alone:

```sh
curl 'https://set.world/api/rarity?indexes=<19-numbers>'
```

## Source

The full source, conventions, and architecture: <https://github.com/jimmylee/set>. Pages Router only. No client SDK.
