> ## Documentation Index
> Fetch the complete documentation index at: https://ttrpg.docs.kitefrost.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Create your first encounter and generate a full session plan in under 5 minutes.

## Prerequisites

* An KiteFrost account ([sign up free](https://app.kitefrost.ai/signup))
* Your `sk_live_...` API key from **Settings → API Keys**

***

## Step 1 - Create an encounter

Define the encounter context. The engine uses your campaign's project state to generate balanced, flavourful output.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.kitefrost.io/v1/encounters \
    -H "Authorization: Bearer sk_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "ruleset": "dnd5e",
      "party_size": 4,
      "party_level": 5,
      "difficulty": "hard",
      "environment": "abandoned dwarven mine",
      "narrative_context": "Players are chasing a thieves guild courier who fled into the mines",
      "monster_preferences": ["undead", "constructs"]
    }'
  ```

  ```python Python theme={null}
  import requests

  encounter = requests.post(
      "https://api.kitefrost.io/v1/encounters",
      headers={"Authorization": "Bearer sk_live_your_key_here"},
      json={
          "ruleset": "dnd5e",
          "party_size": 4,
          "party_level": 5,
          "difficulty": "hard",
          "environment": "abandoned dwarven mine",
          "narrative_context": "Players are chasing a thieves guild courier who fled into the mines",
          "monster_preferences": ["undead", "constructs"],
      },
  ).json()
  print(encounter["id"])  # enc_01HZ...
  ```

  ```typescript TypeScript theme={null}
  const encounter = await fetch("https://api.kitefrost.io/v1/encounters", {
    method: "POST",
    headers: {
      Authorization: "Bearer sk_live_your_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      ruleset: "dnd5e",
      party_size: 4,
      party_level: 5,
      difficulty: "hard",
      environment: "abandoned dwarven mine",
      narrative_context: "Players are chasing a thieves guild courier who fled into the mines",
      monster_preferences: ["undead", "constructs"],
    }),
  }).then((r) => r.json());
  ```
</CodeGroup>

***

## Step 2 - Generate a session plan

Pass the encounter id (and any other hooks already in your campaign) to get a full session outline with pacing, contingencies, and boxed read-aloud text.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.kitefrost.io/v1/sessions/plan \
    -H "Authorization: Bearer sk_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "session_number": 7,
      "opening_hook": "The courier drops a coded letter before fleeing deeper into the mine",
      "encounter_ids": ["enc_01HZ..."],
      "desired_length_hours": 3,
      "tone": "tense, investigative"
    }'
  ```

  ```json Response theme={null}
  {
    "id": "plan_01HZ...",
    "session_number": 7,
    "scenes": [
      {
        "order": 1,
        "title": "The Chase Begins",
        "description": "Players enter the mine entrance. Flickering torchlight. The sound of running feet ahead.",
        "read_aloud": "The mine yawns before you, the stench of old iron and damp stone filling your lungs...",
        "estimated_minutes": 20,
        "type": "exploration"
      },
      {
        "order": 2,
        "title": "Ambush at the Smelting Chamber",
        "description": "Encounter enc_01HZ... - four Animated Armours guard a barricaded door.",
        "estimated_minutes": 45,
        "type": "combat"
      }
    ],
    "contingencies": [
      "If players bypass the combat: courier is cornered in the treasure vault (scene 4)",
      "If a PC is knocked unconscious: a friendly duergar ghost offers a bargain"
    ],
    "generation_ms": 1240
  }
  ```
</CodeGroup>

***

## Step 3 - Track items, quests, and notes

A campaign is more than encounters. Track the loot the players are hunting, the quests they have signed on for, and the lore they have uncovered. Every entity has its own dashboard page and its own REST endpoint.

### Track your loot - create an item

Items are gear, treasures, set pieces, and macguffins. They live alongside NPCs and Places in the campaign and can be referenced from quest rewards, encounter loot, or location inventories.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.kitefrost.io/v1/projects/{project_id}/ttrpg-gm/items \
    -H "Authorization: Bearer sk_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Sunset Edge",
      "properties": {
        "description": "A curved blade that shimmers gold at dawn and dusk",
        "rarity": "rare",
        "item_type": "weapon"
      }
    }'
  ```

  ```python Python theme={null}
  item = requests.post(
      f"https://api.kitefrost.io/v1/projects/{project_id}/ttrpg-gm/items",
      headers={"Authorization": "Bearer sk_live_your_key_here"},
      json={
          "name": "Sunset Edge",
          "properties": {
              "description": "A curved blade that shimmers gold at dawn and dusk",
              "rarity": "rare",
              "item_type": "weapon",
          },
      },
  ).json()
  ```
</CodeGroup>

The dashboard's **Items** page lists every item in the campaign and lets you create more from a simple form. Vocabulary follows your campaign - in the TTRPG GM pack these objects are called "Items".

### Plan a quest - create a quest with objectives

Quests track multi-step adventure threads. Each quest has a status (`offered` → `active` → `completed`), a list of objectives, and optional links to a quest-giver NPC and reward items.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.kitefrost.io/v1/projects/{project_id}/quests \
    -H "Authorization: Bearer sk_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "The Courier'\''s Letter",
      "summary": "Recover the coded letter the courier dropped in the mines",
      "status": "active",
      "objectives": [
        { "text": "Catch the courier before they reach the lower vault", "order": 1 },
        { "text": "Recover the letter intact", "order": 2 },
        { "text": "Decipher the cipher with help from the duergar ghost", "order": 3 }
      ]
    }'
  ```

  ```python Python theme={null}
  quest = requests.post(
      f"https://api.kitefrost.io/v1/projects/{project_id}/quests",
      headers={"Authorization": "Bearer sk_live_your_key_here"},
      json={
          "title": "The Courier's Letter",
          "summary": "Recover the coded letter the courier dropped in the mines",
          "status": "active",
          "objectives": [
              {"text": "Catch the courier before they reach the lower vault", "order": 1},
              {"text": "Recover the letter intact", "order": 2},
              {"text": "Decipher the cipher with help from the duergar ghost", "order": 3},
          ],
      },
  ).json()
  ```
</CodeGroup>

Toggle each objective complete from the dashboard or by patching the quest. When every objective is done, set `status: "completed"` and link the session that resolved it via `completed_session_id`.

### Capture lore - create a note

Notes are free-form Markdown text - use them for lore, rumours, house rules, and post-session recaps. Pin the ones you reach for every session so they sort to the top.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.kitefrost.io/v1/projects/{project_id}/notes \
    -H "Authorization: Bearer sk_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "title": "House rule: Critical hits explode",
      "body": "On a natural 20, the player rolls the damage die again and adds it. Stacks recursively on another 20.",
      "note_type": "house_rule",
      "pinned": true,
      "tags": ["combat", "rules"]
    }'
  ```

  ```python Python theme={null}
  note = requests.post(
      f"https://api.kitefrost.io/v1/projects/{project_id}/notes",
      headers={"Authorization": "Bearer sk_live_your_key_here"},
      json={
          "title": "House rule: Critical hits explode",
          "body": "On a natural 20, the player rolls the damage die again and adds it. Stacks recursively on another 20.",
          "note_type": "house_rule",
          "pinned": True,
          "tags": ["combat", "rules"],
      },
  ).json()
  ```
</CodeGroup>

Pick a `note_type` to file the note in a category - `lore`, `rumour`, `house_rule`, `recap`, `secret` are common values; the field is free text so use whatever taxonomy fits your table. Pinned notes sort first; the rest sort by most recently updated.

***

## Step 4 - Record session outcomes

After the session, record what actually happened so the project state updates for next time.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.kitefrost.io/v1/sessions/plan_01HZ.../outcomes \
    -H "Authorization: Bearer sk_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "completed_scenes": [1, 2],
      "skipped_scenes": [],
      "notable_events": [
        "Players captured the courier",
        "One PC made an alliance with the duergar ghost"
      ]
    }'
  ```
</CodeGroup>

***

## Next steps

* Browse [Encounter endpoints](/api-reference#tag/encounters) for stat block export and CR adjustment
* Use [BYOK](_shared/core-concepts/byok) to route generation through your own LLM provider key
* Subscribe to `generation.completed` [webhooks](_shared/core-concepts/webhooks) to stream results to your VTT
