Files
Code_of_Conquest/api/docs/API_REFERENCE.md
2025-11-25 16:05:42 -06:00

50 KiB
Raw Blame History

API Reference

All API responses follow standardized format:

{
  "app": "AI Dungeon Master",
  "version": "1.0.0",
  "status": 200,
  "timestamp": "2025-11-14T12:00:00Z",
  "request_id": "optional-request-id",
  "result": {},
  "error": null,
  "meta": {}
}

Base URL: /api/v1


Authentication

Authentication handled by Appwrite with HTTP-only cookies. Sessions are stored in coc_session cookie.

Cookie Configuration:

  • Name: coc_session
  • HTTP-only: true (JavaScript cannot access)
  • Secure: true (HTTPS only in production)
  • SameSite: Lax (CSRF protection)
  • Duration (normal): 24 hours
  • Duration (remember me): 30 days

Register

Endpoint POST /api/v1/auth/register
Description Create new user account with email verification
Auth Required No

Request Body:

{
  "email": "player@example.com",
  "password": "SecurePass123!",
  "name": "Adventurer"
}

Response (201 Created):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 201,
  "timestamp": "2025-11-14T12:00:00Z",
  "result": {
    "user": {
      "id": "user_id_123",
      "email": "player@example.com",
      "name": "Adventurer",
      "email_verified": false,
      "tier": "free",
      "created_at": "2025-11-14T12:00:00Z"
    },
    "message": "Registration successful. Please check your email to verify your account."
  }
}

Login

Endpoint POST /api/v1/auth/login
Description User login with session cookie
Auth Required No

Request Body:

{
  "email": "player@example.com",
  "password": "SecurePass123!",
  "remember_me": true
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-14T12:00:00Z",
  "result": {
    "user": {
      "id": "user_id_123",
      "email": "player@example.com",
      "name": "Adventurer",
      "email_verified": true,
      "tier": "free"
    },
    "message": "Login successful"
  }
}

Set-Cookie Header:

Set-Cookie: coc_session=<session_token>; HttpOnly; Secure; SameSite=Lax; Max-Age=2592000; Path=/

Logout

Endpoint POST /api/v1/auth/logout
Description Logout current session and clear cookie
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-14T12:00:00Z",
  "result": {
    "message": "Logout successful"
  }
}

Verify Email

Endpoint GET /api/v1/auth/verify-email
Description Verify user email address
Auth Required No

Query Parameters:

  • userId - User ID from verification email
  • secret - Verification secret from email

Success: Redirects to /auth/login?verified=true Error: Redirects to /auth/login?verified=false

Forgot Password

Endpoint POST /api/v1/auth/forgot-password
Description Request password reset email
Auth Required No

Request Body:

{
  "email": "player@example.com"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-14T12:00:00Z",
  "result": {
    "message": "If an account exists with this email, you will receive a password reset link shortly."
  }
}

Reset Password (Display Form)

Endpoint GET /api/v1/auth/reset-password
Description Display password reset form
Auth Required No

Query Parameters:

  • userId - User ID from reset email
  • secret - Reset secret from email

Success: Renders password reset form

Reset Password (Submit)

Endpoint POST /api/v1/auth/reset-password
Description Submit new password
Auth Required No

Request Body:

{
  "user_id": "user_id_123",
  "secret": "reset_secret",
  "password": "NewSecurePass123!"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-14T12:00:00Z",
  "result": {
    "message": "Password reset successful. You can now log in with your new password."
  }
}

Characters

List Characters

Endpoint GET /api/v1/characters
Description Get all characters for current user with tier information
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "characters": [
      {
        "character_id": "char_123",
        "name": "Thorin Ironheart",
        "class": "vanguard",
        "class_name": "Vanguard",
        "level": 5,
        "experience": 250,
        "gold": 1000,
        "current_location": "forgotten_crypt",
        "origin": "soul_revenant"
      }
    ],
    "count": 1,
    "tier": "free",
    "limit": 1
  }
}

Get Character

Endpoint GET /api/v1/characters/<id>
Description Get full character details including inventory, equipment, and skills
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "character_id": "char_123",
    "user_id": "user_456",
    "name": "Thorin Ironheart",
    "player_class": {
      "class_id": "vanguard",
      "name": "Vanguard",
      "description": "A seasoned warrior...",
      "base_stats": {
        "strength": 14,
        "dexterity": 10,
        "constitution": 14,
        "intelligence": 8,
        "wisdom": 10,
        "charisma": 9
      },
      "skill_trees": [
        {
          "tree_id": "shield_bearer",
          "name": "Shield Bearer",
          "description": "Defensive tanking specialization",
          "nodes": []
        }
      ],
      "starting_equipment": ["rusty_sword"],
      "starting_abilities": ["basic_attack"]
    },
    "origin": {
      "id": "soul_revenant",
      "name": "Soul Revenant",
      "description": "Returned from death...",
      "starting_location": {
        "id": "forgotten_crypt",
        "name": "The Forgotten Crypt",
        "region": "The Deadlands",
        "description": "An ancient burial site..."
      },
      "narrative_hooks": [],
      "starting_bonus": {}
    },
    "level": 5,
    "experience": 250,
    "base_stats": {
      "strength": 14,
      "dexterity": 10,
      "constitution": 14,
      "intelligence": 8,
      "wisdom": 10,
      "charisma": 9
    },
    "unlocked_skills": ["shield_bash", "iron_defense"],
    "inventory": [],
    "equipped": {},
    "gold": 1000,
    "active_quests": [],
    "discovered_locations": ["forgotten_crypt"],
    "current_location": "forgotten_crypt"
  }
}

Error Response (404 Not Found):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 404,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": null,
  "error": {
    "code": "NOT_FOUND",
    "message": "Character not found: char_999",
    "details": {}
  }
}

Create Character

Endpoint POST /api/v1/characters
Description Create new character (validates tier limits)
Auth Required Yes

Request Body:

{
  "name": "Thorin Ironheart",
  "class_id": "vanguard",
  "origin_id": "soul_revenant"
}

Validation Rules:

  • name: 2-50 characters, letters/numbers/spaces/hyphens/apostrophes only
  • class_id: Must be one of: vanguard, assassin, arcanist, luminary, wildstrider, oathkeeper, necromancer, lorekeeper
  • origin_id: Must be one of: soul_revenant, memory_thief, shadow_apprentice, escaped_captive

Response (201 Created):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 201,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "character_id": "char_123",
    "name": "Thorin Ironheart",
    "class": "vanguard",
    "class_name": "Vanguard",
    "origin": "soul_revenant",
    "origin_name": "Soul Revenant",
    "level": 1,
    "gold": 0,
    "current_location": "forgotten_crypt",
    "message": "Character created successfully"
  }
}

Error Response (400 Bad Request - Limit Exceeded):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 400,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": null,
  "error": {
    "code": "CHARACTER_LIMIT_EXCEEDED",
    "message": "Character limit reached for free tier (1/1). Upgrade your subscription to create more characters.",
    "details": {}
  }
}

Error Response (400 Bad Request - Validation Error):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 400,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": null,
  "error": {
    "code": "INVALID_INPUT",
    "message": "Validation failed",
    "details": {
      "name": "Character name must be at least 2 characters",
      "class_id": "Invalid class ID. Must be one of: vanguard, assassin, arcanist, luminary, wildstrider, oathkeeper, necromancer, lorekeeper"
    }
  }
}

Delete Character

Endpoint DELETE /api/v1/characters/<id>
Description Delete character (soft delete - marks as inactive)
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "message": "Character deleted successfully",
    "character_id": "char_123"
  }
}

Unlock Skill

Endpoint POST /api/v1/characters/<id>/skills/unlock
Description Unlock skill node (validates prerequisites and skill points)
Auth Required Yes

Request Body:

{
  "skill_id": "shield_bash"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "message": "Skill unlocked successfully",
    "character_id": "char_123",
    "skill_id": "shield_bash",
    "unlocked_skills": ["shield_bash"],
    "available_points": 0
  }
}

Error Response (400 Bad Request - Prerequisites Not Met):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 400,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": null,
  "error": {
    "code": "SKILL_UNLOCK_ERROR",
    "message": "Prerequisite not met: iron_defense required for fortified_resolve",
    "details": {}
  }
}

Error Response (400 Bad Request - No Skill Points):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 400,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": null,
  "error": {
    "code": "SKILL_UNLOCK_ERROR",
    "message": "No skill points available (Level 1, 1 skills unlocked)",
    "details": {}
  }
}

Respec Skills

Endpoint POST /api/v1/characters/<id>/skills/respec
Description Reset all unlocked skills (costs level × 100 gold)
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "message": "Skills reset successfully",
    "character_id": "char_123",
    "cost": 500,
    "remaining_gold": 500,
    "available_points": 5
  }
}

Error Response (400 Bad Request - Insufficient Gold):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 400,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": null,
  "error": {
    "code": "INSUFFICIENT_GOLD",
    "message": "Insufficient gold for respec. Cost: 500, Available: 100",
    "details": {}
  }
}

Classes & Origins (Reference Data)

List Classes

Endpoint GET /api/v1/classes
Description Get all available player classes
Auth Required No

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "classes": [
      {
        "class_id": "vanguard",
        "name": "Vanguard",
        "description": "A seasoned warrior who stands at the front lines...",
        "base_stats": {
          "strength": 14,
          "dexterity": 10,
          "constitution": 14,
          "intelligence": 8,
          "wisdom": 10,
          "charisma": 9
        },
        "skill_trees": ["Shield Bearer", "Weapon Master"],
        "starting_equipment": ["rusty_sword"],
        "starting_abilities": ["basic_attack"]
      },
      {
        "class_id": "assassin",
        "name": "Assassin",
        "description": "A master of stealth and precision...",
        "base_stats": {
          "strength": 11,
          "dexterity": 15,
          "constitution": 10,
          "intelligence": 9,
          "wisdom": 10,
          "charisma": 10
        },
        "skill_trees": ["Shadow Dancer", "Blade Specialist"],
        "starting_equipment": ["rusty_dagger"],
        "starting_abilities": ["basic_attack"]
      }
    ],
    "count": 8
  }
}

Get Class

Endpoint GET /api/v1/classes/<class_id>
Description Get full class details with skill trees
Auth Required No

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "class_id": "vanguard",
    "name": "Vanguard",
    "description": "A seasoned warrior who stands at the front lines...",
    "base_stats": {
      "strength": 14,
      "dexterity": 10,
      "constitution": 14,
      "intelligence": 8,
      "wisdom": 10,
      "charisma": 9
    },
    "skill_trees": [
      {
        "tree_id": "shield_bearer",
        "name": "Shield Bearer",
        "description": "Defensive tanking specialization",
        "nodes": [
          {
            "skill_id": "shield_bash",
            "name": "Shield Bash",
            "description": "Strike with shield for 120% damage and 1-turn stun",
            "tier": 1,
            "prerequisites": [],
            "effects": {
              "damage_multiplier": 1.2
            },
            "unlocks_abilities": ["shield_bash"]
          }
        ]
      },
      {
        "tree_id": "weapon_master",
        "name": "Weapon Master",
        "description": "Offensive damage specialization",
        "nodes": []
      }
    ],
    "starting_equipment": ["rusty_sword"],
    "starting_abilities": ["basic_attack"]
  }
}

Error Response (404 Not Found):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 404,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": null,
  "error": {
    "code": "NOT_FOUND",
    "message": "Class not found: invalid_class",
    "details": {}
  }
}

List Origins

Endpoint GET /api/v1/origins
Description Get all available character origins
Auth Required No

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-15T12:00:00Z",
  "result": {
    "origins": [
      {
        "id": "soul_revenant",
        "name": "Soul Revenant",
        "description": "Centuries ago, you perished in battle...",
        "starting_location": {
          "id": "forgotten_crypt",
          "name": "The Forgotten Crypt",
          "region": "The Deadlands",
          "description": "An ancient burial site shrouded in mist..."
        },
        "narrative_hooks": [
          "Why were you brought back to life?",
          "What happened in the centuries you were dead?",
          "Do you remember your past life?",
          "Who or what resurrected you?",
          "Are there others like you?",
          "What is your purpose now?"
        ],
        "starting_bonus": {
          "trait": "Deathless Resolve",
          "description": "Having already died once, death holds no fear for you",
          "effect": "Once per day, when reduced to 0 HP, survive with 1 HP instead"
        }
      }
    ],
    "count": 4
  }
}

Health

Health Check

Endpoint GET /api/v1/health
Description Check API service status and version
Auth Required No

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": {
    "status": "ok",
    "service": "Code of Conquest API",
    "version": "0.1.0"
  },
  "error": null,
  "meta": {}
}

Sessions

List Sessions

Endpoint GET /api/v1/sessions
Description Get all active sessions for current user
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": [
    {
      "session_id": "sess_789",
      "character_id": "char_456",
      "turn_number": 5,
      "status": "active",
      "created_at": "2025-11-16T10:00:00Z",
      "last_activity": "2025-11-16T10:25:00Z",
      "game_state": {
        "current_location": "crossville_village",
        "location_type": "town"
      }
    }
  ]
}

Error Responses:

  • 401 - Not authenticated
  • 500 - Internal server error

Create Session

Endpoint POST /api/v1/sessions
Description Create new solo game session
Auth Required Yes

Request Body:

{
  "character_id": "char_456"
}

Response (201 Created):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 201,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": {
    "session_id": "sess_789",
    "character_id": "char_456",
    "turn_number": 0,
    "game_state": {
      "current_location": "Crossroads Village",
      "location_type": "town",
      "active_quests": []
    }
  }
}

Error Responses:

  • 400 - Validation error (missing character_id)
  • 404 - Character not found
  • 409 - Session limit exceeded (max 5 active sessions)

Get Session State

Endpoint GET /api/v1/sessions/<session_id>
Description Get current session state with available actions
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": {
    "session_id": "sess_789",
    "character_id": "char_456",
    "turn_number": 5,
    "status": "active",
    "game_state": {
      "current_location": "The Rusty Anchor",
      "location_type": "tavern",
      "active_quests": ["quest_goblin_cave"]
    },
    "available_actions": [
      {
        "prompt_id": "ask_locals",
        "display_text": "Ask locals for information",
        "description": "Talk to NPCs to learn about quests and rumors",
        "category": "ask_question"
      },
      {
        "prompt_id": "rest",
        "display_text": "Rest and recover",
        "description": "Take a short rest to recover health",
        "category": "rest"
      }
    ]
  }
}

Error Responses:

  • 404 - Session not found or not owned by user

Take Action

Endpoint POST /api/v1/sessions/<session_id>/action
Description Submit action for AI processing (async)
Auth Required Yes

Request Body:

{
  "action_type": "button",
  "prompt_id": "ask_locals"
}

Response (202 Accepted):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 202,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": {
    "job_id": "abc-123",
    "status": "queued",
    "message": "Your action is being processed..."
  }
}

Notes:

  • Only button actions with predefined prompts are supported
  • Poll /api/v1/jobs/<job_id>/status to check processing status
  • Rate limits apply based on subscription tier
  • Available actions depend on user tier and current location

Error Responses:

  • 400 - Validation error (invalid action_type, missing prompt_id)
  • 403 - Action not available for tier/location
  • 404 - Session not found
  • 429 - Rate limit exceeded

Rate Limit Error Response (429):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 429,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": null,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Daily turn limit reached (20 turns). Resets at 00:00 UTC",
    "details": {}
  }
}

Get Job Status

Endpoint GET /api/v1/jobs/<job_id>/status
Description Get status of an async AI processing job
Auth Required Yes

Response (200 OK - Processing):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:05Z",
  "result": {
    "job_id": "ai_TaskType.NARRATIVE_abc123",
    "status": "processing"
  }
}

Response (200 OK - Completed):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:10Z",
  "result": {
    "job_id": "ai_TaskType.NARRATIVE_abc123",
    "status": "completed",
    "dm_response": "As you search for supplies in the village, you notice...",
    "tokens_used": 273,
    "model": "meta/meta-llama-3-8b-instruct"
  }
}

Response (200 OK - Failed):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:10Z",
  "result": {
    "job_id": "ai_TaskType.NARRATIVE_abc123",
    "status": "failed",
    "error": "AI generation failed"
  }
}

Error Responses:

  • 404 - Job not found

Get Conversation History

Endpoint GET /api/v1/sessions/<session_id>/history
Description Get paginated conversation history
Auth Required Yes

Query Parameters:

  • limit (int, default 20, max 100) - Number of entries to return
  • offset (int, default 0) - Number of entries to skip

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": {
    "total_turns": 5,
    "history": [
      {
        "turn": 1,
        "action": "I explore the tavern",
        "dm_response": "You enter a smoky tavern filled with weary travelers...",
        "timestamp": "2025-11-16T10:30:00Z"
      },
      {
        "turn": 2,
        "action": "Ask locals for information",
        "dm_response": "A grizzled dwarf at the bar tells you about goblin raids...",
        "timestamp": "2025-11-16T10:32:00Z"
      }
    ],
    "pagination": {
      "limit": 20,
      "offset": 0,
      "has_more": false
    }
  }
}

Error Responses:

  • 404 - Session not found

End Session

Endpoint DELETE /api/v1/sessions/<session_id>
Description End and archive session
Auth Required Yes

Response (200 OK):

{
  "result": {
    "message": "Session ended",
    "final_state": {}
  }
}

Export Session

Endpoint GET /api/v1/sessions/<session_id>/export
Description Export session log as Markdown
Auth Required Yes

Response:

# Session Log: sess_789
**Date:** 2025-11-14
**Character:** Aragorn the Brave

## Turn 1
**Action:** I explore the tavern
**DM:** You enter a smoky tavern...

Travel

The Travel API enables location-based world exploration. Locations are defined in YAML files and players can travel to any unlocked (discovered) location.

Get Available Destinations

Endpoint GET /api/v1/travel/available
Description Get all locations the player can travel to
Auth Required Yes

Query Parameters:

  • session_id (required) - Active session ID

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "current_location": "crossville_village",
    "destinations": [
      {
        "location_id": "crossville_tavern",
        "name": "The Rusty Anchor Tavern",
        "location_type": "tavern",
        "region_id": "crossville",
        "description": "A cozy tavern where travelers share tales..."
      },
      {
        "location_id": "crossville_forest",
        "name": "Whispering Woods",
        "location_type": "wilderness",
        "region_id": "crossville",
        "description": "A dense forest on the outskirts of town..."
      }
    ]
  }
}

Error Responses:

  • 400 - Missing session_id parameter
  • 404 - Session or character not found
  • 500 - Internal server error

Travel to Location

Endpoint POST /api/v1/travel
Description Travel to a new location (must be discovered)
Auth Required Yes

Request Body:

{
  "session_id": "sess_789",
  "location_id": "crossville_tavern"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "location": {
      "location_id": "crossville_tavern",
      "name": "The Rusty Anchor Tavern",
      "location_type": "tavern",
      "region_id": "crossville",
      "description": "A cozy tavern where travelers share tales...",
      "lore": "Founded decades ago by a retired adventurer...",
      "ambient_description": "The scent of ale and roasting meat fills the air...",
      "available_quests": ["quest_missing_trader"],
      "npc_ids": ["npc_grom_ironbeard"],
      "discoverable_locations": ["crossville_forest"],
      "is_starting_location": false,
      "tags": ["tavern", "social", "merchant", "safe"]
    },
    "npcs_present": [
      {
        "npc_id": "npc_grom_ironbeard",
        "name": "Grom Ironbeard",
        "role": "bartender",
        "appearance": "Stout dwarf with a braided grey beard"
      }
    ],
    "game_state": {
      "current_location": "crossville_tavern",
      "location_type": "tavern",
      "active_quests": []
    }
  }
}

Error Responses:

  • 400 - Location not discovered
  • 403 - Location not discovered
  • 404 - Session or location not found
  • 500 - Internal server error

Get Location Details

Endpoint GET /api/v1/travel/location/<location_id>
Description Get full details for a specific location
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "location": {
      "location_id": "crossville_village",
      "name": "Crossville Village",
      "location_type": "town",
      "region_id": "crossville",
      "description": "A modest farming village built around a central square...",
      "lore": "Founded two centuries ago by settlers from the eastern kingdoms...",
      "ambient_description": "The village square bustles with activity...",
      "available_quests": ["quest_mayors_request"],
      "npc_ids": ["npc_mayor_aldric", "npc_blacksmith_hilda"],
      "discoverable_locations": ["crossville_tavern", "crossville_forest"],
      "is_starting_location": true,
      "tags": ["town", "social", "merchant", "safe"]
    },
    "npcs_present": [
      {
        "npc_id": "npc_mayor_aldric",
        "name": "Mayor Aldric",
        "role": "village mayor",
        "appearance": "A portly man in fine robes"
      }
    ]
  }
}

Error Responses:

  • 404 - Location not found
  • 500 - Internal server error

Get Current Location

Endpoint GET /api/v1/travel/current
Description Get current location details with NPCs present
Auth Required Yes

Query Parameters:

  • session_id (required) - Active session ID

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "location": {
      "location_id": "crossville_village",
      "name": "Crossville Village",
      "location_type": "town",
      "description": "A modest farming village..."
    },
    "npcs_present": [
      {
        "npc_id": "npc_mayor_aldric",
        "name": "Mayor Aldric",
        "role": "village mayor"
      },
      {
        "npc_id": "npc_blacksmith_hilda",
        "name": "Hilda Ironforge",
        "role": "blacksmith"
      }
    ]
  }
}

NPCs

The NPC API enables interaction with persistent NPCs. NPCs have personalities, knowledge, and relationships that affect dialogue generation.

Get NPC Details

Endpoint GET /api/v1/npcs/<npc_id>
Description Get NPC details with knowledge filtered by relationship
Auth Required Yes

Query Parameters:

  • character_id (optional) - Filter knowledge by character's relationship

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "npc_id": "npc_grom_ironbeard",
    "name": "Grom Ironbeard",
    "role": "bartender",
    "location_id": "crossville_tavern",
    "image_url": "/static/images/npcs/crossville/grom_ironbeard.png",
    "personality": {
      "traits": ["gruff", "observant", "secretly kind"],
      "speech_style": "Uses dwarven expressions, speaks in short sentences",
      "quirks": ["Polishes same mug when thinking", "Snorts when amused"]
    },
    "appearance": {
      "brief": "Stout dwarf with a braided grey beard",
      "detailed": "A weathered dwarf with deep-set eyes..."
    },
    "available_knowledge": [
      "The mayor has been acting strange lately",
      "Strange lights seen in the forest"
    ],
    "interaction_summary": {
      "interaction_count": 3,
      "relationship_level": 65,
      "first_met": "2025-11-20T10:30:00Z"
    },
    "tags": ["merchant", "quest_giver", "information"]
  }
}

Talk to NPC

Endpoint POST /api/v1/npcs/<npc_id>/talk
Description Start or continue conversation with NPC (generates AI dialogue)
Auth Required Yes

Request Body (Initial Greeting):

{
  "session_id": "sess_789",
  "topic": "greeting"
}

Request Body (Player Response - Bidirectional Dialogue):

{
  "session_id": "sess_789",
  "player_response": "What can you tell me about the bandits?"
}

Parameters:

  • session_id (required): Active game session ID
  • topic (optional): Conversation topic for initial greeting (default: "greeting")
  • player_response (optional): Player's custom message to the NPC. If provided, overrides topic. Enables bidirectional conversation.

Response (202 Accepted):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 202,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "job_id": "ai_npc_dialogue_xyz789",
    "status": "queued",
    "message": "Starting conversation with Grom Ironbeard...",
    "npc_name": "Grom Ironbeard",
    "npc_role": "bartender"
  }
}

Job Result (when completed):

{
  "job_id": "ai_npc_dialogue_xyz789",
  "status": "completed",
  "result": {
    "context_type": "npc_dialogue",
    "dialogue": "*polishes mug thoughtfully* \"Ah, another adventurer. What'll it be?\"",
    "tokens_used": 728,
    "npc_name": "Grom Ironbeard",
    "npc_id": "npc_grom_ironbeard",
    "character_name": "Thorin",
    "player_line": "greeting",
    "conversation_history": [
      {
        "player_line": "Hello there!",
        "npc_response": "*nods gruffly* \"Welcome to the Rusty Anchor.\""
      },
      {
        "player_line": "What's the news around town?",
        "npc_response": "*leans in* \"Strange folk been coming through lately...\""
      }
    ]
  }
}

Conversation History:

  • Previous dialogue exchanges are automatically stored per character-NPC pair
  • Up to 10 exchanges are kept per NPC (oldest are pruned)
  • The AI receives the last 3 exchanges as context for continuity
  • The job result includes prior conversation_history for UI display

Bidirectional Dialogue:

  • If player_response is provided in the request, it overrides topic and enables full bidirectional conversation
  • The player's response is stored in the conversation history
  • The NPC's reply takes into account the full conversation context

Error Responses:

  • 400 - NPC not at current location
  • 404 - NPC or session not found

Get NPCs at Location

Endpoint GET /api/v1/npcs/at-location/<location_id>
Description Get all NPCs present at a location
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "location_id": "crossville_tavern",
    "npcs": [
      {
        "npc_id": "npc_grom_ironbeard",
        "name": "Grom Ironbeard",
        "role": "bartender",
        "appearance": "Stout dwarf with a braided grey beard",
        "tags": ["merchant", "quest_giver"],
        "image_url": "/static/images/npcs/crossville/grom_ironbeard.png"
      },
      {
        "npc_id": "npc_mira_swiftfoot",
        "name": "Mira Swiftfoot",
        "role": "traveling rogue",
        "appearance": "Lithe half-elf with sharp eyes",
        "tags": ["information", "secret_keeper"],
        "image_url": "/static/images/npcs/crossville/mira_swiftfoot.png"
      }
    ]
  }
}

Adjust NPC Relationship

Endpoint POST /api/v1/npcs/<npc_id>/relationship
Description Adjust relationship level with NPC
Auth Required Yes

Request Body:

{
  "character_id": "char_123",
  "adjustment": 10
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "npc_id": "npc_grom_ironbeard",
    "relationship_level": 75
  }
}

Set NPC Custom Flag

Endpoint POST /api/v1/npcs/<npc_id>/flag
Description Set custom flag on NPC interaction (for conditional secrets)
Auth Required Yes

Request Body:

{
  "character_id": "char_123",
  "flag_name": "helped_with_rats",
  "flag_value": true
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T10:30:00Z",
  "result": {
    "npc_id": "npc_grom_ironbeard",
    "flag_name": "helped_with_rats",
    "flag_value": true
  }
}

Combat

Attack

Endpoint POST /api/v1/combat/<session_id>/attack
Description Execute physical attack
Auth Required Yes

Request Body:

{
  "attacker_id": "char123",
  "target_id": "enemy1",
  "weapon_id": "sword1"
}

Response:

{
  "result": {
    "damage": 15,
    "critical": true,
    "narrative": "Aragorn's blade strikes true...",
    "target_hp": 25
  }
}

Cast Spell

Endpoint POST /api/v1/combat/<session_id>/cast
Description Cast spell or ability
Auth Required Yes

Request Body:

{
  "caster_id": "char123",
  "spell_id": "fireball",
  "target_id": "enemy1"
}

Response:

{
  "result": {
    "damage": 30,
    "mana_cost": 15,
    "narrative": "Flames engulf the target...",
    "effects_applied": ["burning"]
  }
}

Use Item

Endpoint POST /api/v1/combat/<session_id>/item
Description Use item from inventory
Auth Required Yes

Request Body:

{
  "character_id": "char123",
  "item_id": "health_potion",
  "target_id": "char123"
}

Response:

{
  "result": {
    "healing": 50,
    "narrative": "You drink the potion and feel refreshed",
    "current_hp": 100
  }
}

Defend

Endpoint POST /api/v1/combat/<session_id>/defend
Description Take defensive stance
Auth Required Yes

Request Body:

{
  "character_id": "char123"
}

Response:

{
  "result": {
    "defense_bonus": 10,
    "duration": 1,
    "narrative": "You brace for impact"
  }
}

Get Combat Status

Endpoint GET /api/v1/combat/<session_id>/status
Description Get current combat state
Auth Required Yes

Response:

{
  "result": {
    "combatants": [],
    "turn_order": [],
    "current_turn": 0,
    "round_number": 1,
    "status": "active"
  }
}

Game Mechanics

Endpoint POST /api/v1/game/check
Description Perform a skill check or search action and get deterministic dice roll results
Auth Required Yes

Request Body (Skill Check):

{
  "character_id": "char_123",
  "check_type": "skill",
  "skill": "persuasion",
  "dc": 15,
  "bonus": 2,
  "context": {
    "npc_name": "Guard Captain"
  }
}

Request Body (Search Action):

{
  "character_id": "char_123",
  "check_type": "search",
  "location_type": "forest",
  "dc": 12,
  "bonus": 0
}

Request Body (Using Difficulty Name):

{
  "character_id": "char_123",
  "check_type": "skill",
  "skill": "stealth",
  "difficulty": "hard",
  "bonus": 1
}

Response (200 OK - Skill Check Success):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": {
    "check_result": {
      "roll": 16,
      "modifier": 3,
      "total": 19,
      "dc": 15,
      "success": true,
      "margin": 4,
      "skill_type": "persuasion"
    },
    "context": {
      "skill_used": "persuasion",
      "stat_used": "charisma",
      "npc_name": "Guard Captain"
    }
  }
}

Response (200 OK - Search Success):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": {
    "check_result": {
      "roll": 18,
      "modifier": 2,
      "total": 20,
      "dc": 12,
      "success": true,
      "margin": 8,
      "skill_type": "perception"
    },
    "items_found": [
      {
        "template_key": "ancient_coin",
        "name": "Ancient Coin",
        "description": "A weathered coin from ages past",
        "value": 25
      },
      {
        "template_key": "healing_herb",
        "name": "Healing Herb",
        "description": "A medicinal plant bundle",
        "value": 10
      }
    ],
    "gold_found": 15
  }
}

Response (200 OK - Check Failed):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": {
    "check_result": {
      "roll": 7,
      "modifier": 1,
      "total": 8,
      "dc": 15,
      "success": false,
      "margin": -7,
      "skill_type": "stealth"
    },
    "context": {
      "skill_used": "stealth",
      "stat_used": "dexterity",
      "situation": "Sneaking past guards"
    }
  }
}

Error Response (400 Bad Request - Invalid skill):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 400,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": null,
  "error": {
    "code": "INVALID_INPUT",
    "message": "Invalid skill type",
    "details": {
      "field": "skill",
      "issue": "Must be one of: perception, insight, survival, medicine, stealth, acrobatics, sleight_of_hand, lockpicking, persuasion, deception, intimidation, performance, athletics, arcana, history, investigation, nature, religion, endurance"
    }
  }
}

Error Response (404 Not Found - Character not found):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 404,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": null,
  "error": {
    "code": "NOT_FOUND",
    "message": "Character not found: char_999"
  }
}

Error Response (403 Forbidden - Not character owner):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 403,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": null,
  "error": {
    "code": "FORBIDDEN",
    "message": "You don't have permission to access this character"
  }
}

Notes:

  • check_type must be "search" or "skill"
  • For skill checks, skill is required
  • For search checks, location_type is optional (defaults to "default")
  • dc or difficulty must be provided (dc takes precedence)
  • Valid difficulty values: trivial (5), easy (10), medium (15), hard (20), very_hard (25), nearly_impossible (30)
  • bonus is optional (defaults to 0)
  • context is optional and merged with the response for AI narration
  • Roll uses d20 + stat modifier + optional bonus
  • Margin is calculated as (total - dc)
  • Items found depend on location type and success margin

List Available Skills

Endpoint GET /api/v1/game/skills
Description Get all available skill types with their associated stats
Auth Required No

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": {
    "skills": [
      {
        "name": "perception",
        "stat": "wisdom"
      },
      {
        "name": "insight",
        "stat": "wisdom"
      },
      {
        "name": "survival",
        "stat": "wisdom"
      },
      {
        "name": "medicine",
        "stat": "wisdom"
      },
      {
        "name": "stealth",
        "stat": "dexterity"
      },
      {
        "name": "acrobatics",
        "stat": "dexterity"
      },
      {
        "name": "sleight_of_hand",
        "stat": "dexterity"
      },
      {
        "name": "lockpicking",
        "stat": "dexterity"
      },
      {
        "name": "persuasion",
        "stat": "charisma"
      },
      {
        "name": "deception",
        "stat": "charisma"
      },
      {
        "name": "intimidation",
        "stat": "charisma"
      },
      {
        "name": "performance",
        "stat": "charisma"
      },
      {
        "name": "athletics",
        "stat": "strength"
      },
      {
        "name": "arcana",
        "stat": "intelligence"
      },
      {
        "name": "history",
        "stat": "intelligence"
      },
      {
        "name": "investigation",
        "stat": "intelligence"
      },
      {
        "name": "nature",
        "stat": "intelligence"
      },
      {
        "name": "religion",
        "stat": "intelligence"
      },
      {
        "name": "endurance",
        "stat": "constitution"
      }
    ]
  }
}

Notes:

  • No authentication required
  • Skills are grouped by their associated stat
  • Use the skill names in the skill parameter of the /check endpoint

List Difficulty Levels

Endpoint GET /api/v1/game/difficulties
Description Get all difficulty levels and their DC values
Auth Required No

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-23T10:30:00Z",
  "result": {
    "difficulties": [
      {
        "name": "trivial",
        "dc": 5
      },
      {
        "name": "easy",
        "dc": 10
      },
      {
        "name": "medium",
        "dc": 15
      },
      {
        "name": "hard",
        "dc": 20
      },
      {
        "name": "very_hard",
        "dc": 25
      },
      {
        "name": "nearly_impossible",
        "dc": 30
      }
    ]
  }
}

Notes:

  • No authentication required
  • Use difficulty names in the difficulty parameter of the /check endpoint instead of providing raw DC values
  • DC values range from 5 (trivial) to 30 (nearly impossible)

Marketplace

Browse Listings

Endpoint GET /api/v1/marketplace
Description Browse marketplace listings
Auth Required Yes (Premium+ only)

Query Parameters:

  • type - "auction" or "fixed_price"
  • category - "weapon", "armor", "consumable"
  • min_price - Minimum price
  • max_price - Maximum price
  • sort - "price_asc", "price_desc", "ending_soon"
  • page - Page number
  • limit - Items per page

Response:

{
  "result": {
    "listings": [
      {
        "listing_id": "list123",
        "item": {},
        "listing_type": "auction",
        "current_bid": 500,
        "buyout_price": 1000,
        "auction_end": "2025-11-15T12:00:00Z"
      }
    ],
    "total": 50,
    "page": 1,
    "pages": 5
  }
}

Get Listing

Endpoint GET /api/v1/marketplace/<id>
Description Get listing details
Auth Required Yes (Premium+ only)

Response:

{
  "result": {
    "listing_id": "list123",
    "seller_name": "Aragorn",
    "item": {},
    "listing_type": "auction",
    "current_bid": 500,
    "bid_count": 5,
    "bids": [],
    "auction_end": "2025-11-15T12:00:00Z"
  }
}

Create Listing

Endpoint POST /api/v1/marketplace/list
Description Create new marketplace listing
Auth Required Yes (Premium+ only)

Request Body (Auction):

{
  "character_id": "char123",
  "item_id": "sword1",
  "listing_type": "auction",
  "starting_bid": 100,
  "buyout_price": 1000,
  "duration_hours": 48
}

Request Body (Fixed Price):

{
  "character_id": "char123",
  "item_id": "sword1",
  "listing_type": "fixed_price",
  "price": 500
}

Response:

{
  "result": {
    "listing_id": "list123",
    "message": "Listing created successfully"
  }
}

Place Bid

Endpoint POST /api/v1/marketplace/<id>/bid
Description Place bid on auction
Auth Required Yes (Premium+ only)

Request Body:

{
  "character_id": "char123",
  "amount": 600
}

Response:

{
  "result": {
    "current_bid": 600,
    "is_winning": true,
    "message": "Bid placed successfully"
  }
}

Buyout

Endpoint POST /api/v1/marketplace/<id>/buyout
Description Instant purchase at buyout price
Auth Required Yes (Premium+ only)

Request Body:

{
  "character_id": "char123"
}

Response:

{
  "result": {
    "transaction_id": "trans123",
    "price": 1000,
    "item": {},
    "message": "Purchase successful"
  }
}

Cancel Listing

Endpoint DELETE /api/v1/marketplace/<id>
Description Cancel listing (owner only)
Auth Required Yes (Premium+ only)

Response:

{
  "result": {
    "message": "Listing cancelled, item returned"
  }
}

My Listings

Endpoint GET /api/v1/marketplace/my-listings
Description Get current user's active listings
Auth Required Yes (Premium+ only)

Response:

{
  "result": {
    "listings": [],
    "total": 5
  }
}

My Bids

Endpoint GET /api/v1/marketplace/my-bids
Description Get current user's active bids
Auth Required Yes (Premium+ only)

Response:

{
  "result": {
    "bids": [
      {
        "listing_id": "list123",
        "item": {},
        "your_bid": 500,
        "current_bid": 600,
        "is_winning": false,
        "auction_end": "2025-11-15T12:00:00Z"
      }
    ]
  }
}

Shop

Browse Shop

Endpoint GET /api/v1/shop/items
Description Browse NPC shop inventory
Auth Required Yes

Query Parameters:

  • category - "consumable", "weapon", "armor"

Response:

{
  "result": {
    "items": [
      {
        "item_id": "health_potion",
        "name": "Health Potion",
        "price": 50,
        "stock": -1,
        "description": "Restores 50 HP"
      }
    ]
  }
}

Purchase from Shop

Endpoint POST /api/v1/shop/purchase
Description Buy item from NPC shop
Auth Required Yes

Request Body:

{
  "character_id": "char123",
  "item_id": "health_potion",
  "quantity": 5
}

Response:

{
  "result": {
    "transaction_id": "trans123",
    "total_cost": 250,
    "items_purchased": 5,
    "remaining_gold": 750
  }
}

Error Responses

Standard Error Format

{
  "app": "AI Dungeon Master",
  "version": "1.0.0",
  "status": 400,
  "timestamp": "2025-11-14T12:00:00Z",
  "result": null,
  "error": {
    "code": "INVALID_ACTION",
    "message": "Not your turn",
    "details": {
      "current_turn": "char456",
      "your_character": "char123"
    }
  }
}

Common Error Codes

Code Status Description
UNAUTHORIZED 401 Invalid or missing auth token
FORBIDDEN 403 Insufficient permissions
NOT_FOUND 404 Resource not found
INVALID_INPUT 400 Validation error
RATE_LIMIT_EXCEEDED 429 Too many requests
CHARACTER_LIMIT_EXCEEDED 400 User has reached character limit for their tier
CHARACTER_NOT_FOUND 404 Character does not exist or not accessible
SKILL_UNLOCK_ERROR 400 Skill unlock failed (prerequisites, points, or tier)
INSUFFICIENT_FUNDS 400 Not enough gold
INVALID_ACTION 400 Action not allowed
SESSION_FULL 400 Session at max capacity
NOT_YOUR_TURN 400 Not active player's turn
AI_LIMIT_EXCEEDED 429 Daily AI call limit reached
PREMIUM_REQUIRED 403 Feature requires premium subscription

Rate Limiting

Tier Requests/Minute AI Calls/Day
FREE 30 50
BASIC 60 200
PREMIUM 120 1000
ELITE 300 Unlimited

Rate Limit Headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1699999999

Pagination

Endpoints that return lists support pagination:

Query Parameters:

  • page - Page number (default: 1)
  • limit - Items per page (default: 20, max: 100)

Response Meta:

{
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 100,
    "pages": 5
  }
}

Realtime Events (WebSocket)

Subscribe to session updates:

client.subscribe(
  'databases.main.collections.game_sessions.documents.{sessionId}',
  callback
);

Event Types:

  • Session state change
  • Turn change
  • Combat update
  • Chat message
  • Player joined/left
  • Marketplace bid notification