Files
Code_of_Conquest/api/docs/API_REFERENCE.md

46 KiB
Raw Permalink Blame History

API Reference

All API responses follow standardized format:

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12: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

Session Caching: Sessions are cached in Redis (db 2) to reduce Appwrite API calls by ~90%. Cache TTL is 5 minutes. Sessions are explicitly invalidated on logout and password change.

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"
  }
}

Get Current User

Endpoint GET /api/v1/auth/me
Description Get current authenticated user's data
Auth Required Yes

Response (200 OK):

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

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

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": {}
  }
}

Delete Character

Endpoint DELETE /api/v1/characters/<id>
Description Permanently delete character and all associated game sessions
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
  }
}

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
  }
}

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"]
      }
    ],
    "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"]
          }
        ]
      }
    ],
    "starting_equipment": ["rusty_sword"],
    "starting_abilities": ["basic_attack"]
  }
}

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?"
        ],
        "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
  }
}

Inventory

Get Inventory

Endpoint GET /api/v1/characters/<character_id>/inventory
Description Get character inventory and equipped items
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "inventory": [
      {
        "item_id": "gen_abc123",
        "name": "Flaming Dagger",
        "item_type": "weapon",
        "rarity": "rare",
        "value": 250,
        "description": "A dagger imbued with fire magic"
      }
    ],
    "equipped": {
      "weapon": {
        "item_id": "rusty_sword",
        "name": "Rusty Sword",
        "item_type": "weapon",
        "rarity": "common"
      },
      "helmet": null,
      "chest": null,
      "legs": null,
      "boots": null,
      "gloves": null,
      "ring1": null,
      "ring2": null,
      "amulet": null
    },
    "inventory_count": 5,
    "max_inventory": 100
  }
}

Equip Item

Endpoint POST /api/v1/characters/<character_id>/inventory/equip
Description Equip an item from inventory to a specified slot
Auth Required Yes

Request Body:

{
  "item_id": "gen_abc123",
  "slot": "weapon"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "message": "Equipped Flaming Dagger to weapon slot",
    "equipped": {
      "weapon": {...},
      "helmet": null
    },
    "unequipped_item": {
      "item_id": "rusty_sword",
      "name": "Rusty Sword"
    }
  }
}

Unequip Item

Endpoint POST /api/v1/characters/<character_id>/inventory/unequip
Description Unequip an item from a specified slot (returns to inventory)
Auth Required Yes

Request Body:

{
  "slot": "weapon"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "message": "Unequipped Flaming Dagger from weapon slot",
    "unequipped_item": {...},
    "equipped": {...}
  }
}

Use Item

Endpoint POST /api/v1/characters/<character_id>/inventory/use
Description Use a consumable item from inventory
Auth Required Yes

Request Body:

{
  "item_id": "health_potion_small"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "item_used": "Small Health Potion",
    "effects_applied": [
      {
        "effect_name": "Healing",
        "effect_type": "hot",
        "value": 25,
        "message": "Restored 25 HP"
      }
    ],
    "hp_restored": 25,
    "mp_restored": 0,
    "message": "Used Small Health Potion: Restored 25 HP"
  }
}

Drop Item

Endpoint DELETE /api/v1/characters/<character_id>/inventory/<item_id>
Description Drop (remove) an item from inventory
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "message": "Dropped Rusty Sword",
    "dropped_item": {...},
    "inventory_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",
      "character_name": "Thorin",
      "turn_number": 5,
      "status": "active",
      "created_at": "2025-11-16T10:00:00Z",
      "last_activity": "2025-11-16T10:25:00Z",
      "in_combat": false,
      "game_state": {
        "current_location": "crossville_village",
        "location_type": "town",
        "in_combat": false,
        "combat_round": null
      }
    }
  ]
}

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": []
    }
  }
}

Session Limits by Tier:

Tier Max Active Sessions
FREE 1
BASIC 2
PREMIUM 3
ELITE 5

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",
    "in_combat": false,
    "game_state": {
      "current_location": "The Rusty Anchor",
      "location_type": "tavern",
      "active_quests": ["quest_goblin_cave"],
      "in_combat": false
    },
    "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"
      }
    ]
  }
}

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

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"
  }
}

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"
      }
    ],
    "pagination": {
      "limit": 20,
      "offset": 0,
      "has_more": false
    }
  }
}

Delete Session

Endpoint DELETE /api/v1/sessions/<session_id>
Description Permanently delete a session and all associated chat messages
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-16T10:30:00Z",
  "result": {
    "message": "Session deleted successfully",
    "session_id": "sess_789"
  }
}

Get Usage Information

Endpoint GET /api/v1/usage
Description Get user's daily usage information (turn limits)
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "user_id": "user_123",
    "user_tier": "free",
    "current_usage": 15,
    "daily_limit": 50,
    "remaining": 35,
    "reset_time": "2025-11-27T00:00:00+00:00",
    "is_limited": false,
    "is_unlimited": false
  }
}

Travel

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..."
      }
    ]
  }
}

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": []
    }
  }
}

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": {...},
    "npcs_present": [...]
  }
}

Get Current Location

Endpoint GET /api/v1/travel/current
Description Get details about the current location in a session
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": {...},
    "npcs_present": [...]
  }
}

NPCs

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?"
}

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.\""
      }
    ]
  }
}

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"
      }
    ]
  }
}

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
  }
}

Chat / Conversation History

The Chat API provides access to complete player-NPC conversation history. All dialogue exchanges are stored in the chat_messages collection for unlimited history.

Get All Conversations Summary

Endpoint GET /api/v1/characters/<character_id>/chats
Description Get summary of all NPC conversations for a character
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T14:30:00Z",
  "result": {
    "conversations": [
      {
        "npc_id": "npc_grom_ironbeard",
        "npc_name": "Grom Ironbeard",
        "last_message_timestamp": "2025-11-25T14:30:00Z",
        "message_count": 15,
        "recent_preview": "Aye, the rats in the cellar have been causing trouble..."
      }
    ]
  }
}

Get Conversation with Specific NPC

Endpoint GET /api/v1/characters/<character_id>/chats/<npc_id>
Description Get paginated conversation history with a specific NPC
Auth Required Yes

Query Parameters:

  • limit (optional): Maximum messages to return (default: 50, max: 100)
  • offset (optional): Number of messages to skip (default: 0)

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T14:30:00Z",
  "result": {
    "npc_id": "npc_grom_ironbeard",
    "npc_name": "Grom Ironbeard",
    "total_messages": 15,
    "messages": [
      {
        "message_id": "msg_abc123",
        "character_id": "char_123",
        "npc_id": "npc_grom_ironbeard",
        "player_message": "What rumors have you heard?",
        "npc_response": "*leans in* Strange folk been coming through lately...",
        "timestamp": "2025-11-25T14:30:00Z",
        "context": "dialogue",
        "location_id": "crossville_tavern",
        "session_id": "sess_789",
        "metadata": {},
        "is_deleted": false
      }
    ],
    "pagination": {
      "limit": 50,
      "offset": 0,
      "has_more": false
    }
  }
}

Search Messages

Endpoint GET /api/v1/characters/<character_id>/chats/search
Description Search messages by text with optional filters
Auth Required Yes

Query Parameters:

  • q (required): Search text to find in player_message and npc_response
  • npc_id (optional): Filter by specific NPC
  • context (optional): Filter by message context type
  • date_from (optional): Start date in ISO format
  • date_to (optional): End date in ISO format
  • limit (optional): Maximum messages to return (default: 50, max: 100)
  • offset (optional): Number of messages to skip (default: 0)

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T14:30:00Z",
  "result": {
    "search_text": "quest",
    "filters": {
      "npc_id": "npc_grom_ironbeard",
      "context": "quest_offered",
      "date_from": null,
      "date_to": null
    },
    "total_results": 2,
    "messages": [...],
    "pagination": {
      "limit": 50,
      "offset": 0,
      "has_more": false
    }
  }
}

Delete Message

Endpoint DELETE /api/v1/characters/<character_id>/chats/<message_id>
Description Soft delete a message (privacy/moderation)
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-25T14:30:00Z",
  "result": {
    "message_id": "msg_abc123",
    "deleted": true
  }
}

Combat

Start Combat

Endpoint POST /api/v1/combat/start
Description Start a new combat encounter
Auth Required Yes

Request Body:

{
  "session_id": "sess_123",
  "enemy_ids": ["goblin", "goblin", "goblin_shaman"]
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "encounter_id": "enc_abc123",
    "combatants": [
      {
        "combatant_id": "char_456",
        "name": "Thorin",
        "is_player": true,
        "current_hp": 100,
        "max_hp": 100,
        "current_mp": 50,
        "max_mp": 50,
        "initiative": 15,
        "abilities": ["basic_attack", "shield_bash"]
      }
    ],
    "turn_order": ["char_456", "goblin_0", "goblin_shaman_0", "goblin_1"],
    "current_turn": "char_456",
    "round_number": 1,
    "status": "active"
  }
}

Get Combat State

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

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "in_combat": true,
    "encounter": {
      "encounter_id": "enc_abc123",
      "combatants": [...],
      "turn_order": [...],
      "current_turn": "char_456",
      "round_number": 2,
      "status": "active",
      "combat_log": [
        "Thorin attacks Goblin for 15 damage!",
        "Goblin attacks Thorin for 5 damage!"
      ]
    }
  }
}

Execute Combat Action

Endpoint POST /api/v1/combat/<session_id>/action
Description Execute a combat action for a combatant
Auth Required Yes

Request Body:

{
  "combatant_id": "char_456",
  "action_type": "attack",
  "target_ids": ["goblin_0"],
  "ability_id": "shield_bash"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "success": true,
    "message": "Shield Bash hits Goblin for 18 damage and stuns!",
    "damage_results": [
      {
        "target_id": "goblin_0",
        "damage": 18,
        "is_critical": false
      }
    ],
    "effects_applied": [
      {
        "target_id": "goblin_0",
        "effect": "stunned",
        "duration": 1
      }
    ],
    "combat_ended": false,
    "combat_status": null,
    "next_combatant_id": "goblin_1"
  }
}

Execute Enemy Turn

Endpoint POST /api/v1/combat/<session_id>/enemy-turn
Description Execute the current enemy's turn using AI logic
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "success": true,
    "message": "Goblin attacks Thorin for 8 damage!",
    "damage_results": [...],
    "effects_applied": [],
    "combat_ended": false,
    "combat_status": null,
    "next_combatant_id": "char_456"
  }
}

Attempt Flee

Endpoint POST /api/v1/combat/<session_id>/flee
Description Attempt to flee from combat
Auth Required Yes

Request Body:

{
  "combatant_id": "char_456"
}

Response (200 OK - Success):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "success": true,
    "message": "Successfully fled from combat!",
    "combat_ended": true,
    "combat_status": "fled"
  }
}

End Combat

Endpoint POST /api/v1/combat/<session_id>/end
Description Force end the current combat (debug/admin endpoint)
Auth Required Yes

Request Body:

{
  "outcome": "victory"
}

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "outcome": "victory",
    "rewards": {
      "experience": 100,
      "gold": 50,
      "items": [...],
      "level_ups": []
    }
  }
}

List Enemies

Endpoint GET /api/v1/combat/enemies
Description List all available enemy templates
Auth Required No

Query Parameters:

  • difficulty (optional): Filter by difficulty (easy, medium, hard, boss)
  • tag (optional): Filter by tag (undead, beast, humanoid, etc.)

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "enemies": [
      {
        "enemy_id": "goblin",
        "name": "Goblin Scout",
        "description": "A small, cunning creature...",
        "difficulty": "easy",
        "tags": ["humanoid", "goblinoid"],
        "experience_reward": 15,
        "gold_reward_range": [5, 15]
      }
    ]
  }
}

Get Enemy Details

Endpoint GET /api/v1/combat/enemies/<enemy_id>
Description Get detailed information about a specific enemy template
Auth Required No

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "enemy_id": "goblin",
    "name": "Goblin Scout",
    "description": "A small, cunning creature with sharp claws",
    "base_stats": {
      "strength": 8,
      "dexterity": 14,
      "constitution": 10
    },
    "abilities": ["quick_strike", "dodge"],
    "loot_table": [...],
    "difficulty": "easy",
    "experience_reward": 15,
    "gold_reward_min": 5,
    "gold_reward_max": 15
  }
}

Debug: Reset HP/MP

Endpoint POST /api/v1/combat/<session_id>/debug/reset-hp-mp
Description Reset player combatant's HP and MP to full (debug endpoint)
Auth Required Yes

Response (200 OK):

{
  "app": "Code of Conquest",
  "version": "0.1.0",
  "status": 200,
  "timestamp": "2025-11-27T12:00:00Z",
  "result": {
    "success": true,
    "message": "HP and MP reset to full",
    "current_hp": 100,
    "max_hp": 100,
    "current_mp": 50,
    "max_mp": 50
  }
}

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
      }
    ],
    "gold_found": 15
  }
}

Notes:

  • check_type must be "search" or "skill"
  • For skill checks, skill is required
  • 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)

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": "stealth", "stat": "dexterity"},
      {"name": "persuasion", "stat": "charisma"},
      {"name": "athletics", "stat": "strength"}
    ]
  }
}

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}
    ]
  }
}

Error Responses

Standard Error Format

{
  "app": "Code of Conquest",
  "version": "0.1.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
SESSION_LIMIT_EXCEEDED 409 User has reached session 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_GOLD 400 Not enough gold
INSUFFICIENT_RESOURCES 400 Not enough MP/items for action
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
ALREADY_IN_COMBAT 400 Session is already in combat
NOT_IN_COMBAT 404 Session is not in combat
INVENTORY_FULL 400 Inventory is full
CANNOT_EQUIP 400 Item cannot be equipped
CANNOT_USE_ITEM 400 Item cannot be used

Rate Limiting

Tier Requests/Minute AI Calls/Day Max Sessions
FREE 30 50 1
BASIC 60 200 2
PREMIUM 120 1000 3
ELITE 300 Unlimited 5

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
  }
}