The Quest Chain system provides a comprehensive framework for creating progressive puzzle sequences with story elements, unlock conditions, branching paths, and reward systems.
/quest-chains
POST /quest-chainsRequest Body:
{
"name": "The Mystery of Blackwood Manor",
"description": "Solve the mysteries of the haunted Blackwood Manor",
"status": "active",
"story": {
"intro": "Welcome to Blackwood Manor, where ancient secrets await...",
"outro": "Congratulations! You've solved all the mysteries of Blackwood Manor.",
"chapters": [
{
"id": "chapter1",
"title": "The Locked Study",
"description": "Find the key to unlock the mysterious study",
"storyText": "The study door is locked tight. You notice strange symbols carved around the lock..."
}
]
},
"rewards": {
"completion": {
"xp": 500,
"coins": 250,
"items": ["mystery_solved_badge"]
},
"milestones": [
{
"puzzleIndex": 5,
"rewards": {
"xp": 100,
"coins": 50,
"items": ["chapter_complete_trophy"]
}
}
]
},
"startsAt": "2026-01-01T00:00:00Z",
"endsAt": "2026-12-31T23:59:59Z"
}Response:
{
"id": "chain-uuid",
"name": "The Mystery of Blackwood Manor",
"description": "Solve the mysteries of the haunted Blackwood Manor",
"status": "active",
"story": { ... },
"rewards": { ... },
"completionCount": 0,
"startsAt": "2026-01-01T00:00:00Z",
"endsAt": "2026-12-31T23:59:59Z",
"createdAt": "2026-02-19T12:00:00Z",
"updatedAt": "2026-02-19T12:00:00Z"
}GET /quest-chains?status=active&limit=10&offset=0&sortBy=createdAt&sortOrder=DESCQuery Parameters:
status: Filter by status (active, inactive, archived, all)limit: Number of results (default: 10)offset: Pagination offset (default: 0)sortBy: Sort field (createdAt, completionCount, name)sortOrder: Sort direction (ASC, DESC)
GET /quest-chains/{chainId}PUT /quest-chains/{chainId}DELETE /quest-chains/{chainId}POST /quest-chains/{chainId}/puzzlesRequest Body:
{
"puzzleId": "puzzle-uuid",
"sequenceOrder": 0,
"unlockConditions": {
"previousPuzzles": [],
"minimumScore": 0,
"timeLimit": 300,
"noHints": false
},
"isCheckpoint": true,
"checkpointRewards": {
"xp": 50,
"coins": 25,
"items": ["checkpoint_achieved"]
}
}GET /quest-chains/{chainId}/puzzlesDELETE /quest-chains/{chainId}/puzzles/{puzzleId}GET /quest-chains/{chainId}/validatePOST /quest-chains/{chainId}/startRequest Body:
{
"userId": "user-uuid"
}GET /quest-chains/{chainId}/progressRequest Body:
{
"userId": "user-uuid"
}GET /quest-chains/{chainId}/next-puzzleRequest Body:
{
"userId": "user-uuid"
}POST /quest-chains/{chainId}/puzzles/{puzzleId}/completeRequest Body:
{
"userId": "user-uuid",
"score": 150,
"timeTaken": 120,
"hintsUsed": 1,
"completedSuccessfully": true,
"metadata": {
"difficulty": "medium",
"puzzleType": "logic",
"movesUsed": 8,
"completionMethod": "logical_deduction"
}
}POST /quest-chains/{chainId}/resetRequest Body:
{
"userId": "user-uuid"
}interface QuestChain {
id: string;
name: string;
description: string;
status: 'active' | 'inactive' | 'archived';
story: QuestChainStory;
rewards: QuestChainRewards;
completionCount: number;
startsAt?: Date;
endsAt?: Date;
createdAt: Date;
updatedAt: Date;
}interface QuestChainStory {
intro: string;
outro: string;
chapters: Array<{
id: string;
title: string;
description: string;
storyText: string;
}>;
}interface QuestChainRewards {
completion: {
xp: number;
coins: number;
items: string[];
};
milestones: Array<{
puzzleIndex: number;
rewards: {
xp: number;
coins: number;
items: string[];
};
}>;
}interface UnlockConditions {
previousPuzzles: string[]; // IDs of puzzles that must be completed
minimumScore?: number;
timeLimit?: number; // seconds
noHints?: boolean;
}interface BranchCondition {
conditionType: 'score' | 'time' | 'accuracy' | 'custom';
operator: 'gte' | 'lte' | 'equals' | 'between';
value: number | [number, number];
nextPuzzleId: string; // ID of next puzzle in branch path
}All endpoints return appropriate HTTP status codes:
200: Success201: Created204: No Content (successful deletion)400: Bad Request404: Not Found500: Internal Server Error
Error response format:
{
"statusCode": 400,
"message": "Error description",
"error": "Bad Request"
}- Chain name must be 1-200 characters
- Story must include intro and outro
- Chapters must have valid IDs and titles
- Rewards must have non-negative values
- Sequential order should be continuous (0,1,2... or 1,2,3...)
- Previous puzzle IDs must exist in the chain
- Minimum score must be non-negative
- Time limit must be positive
- First puzzle should not have previous puzzle requirements
- Condition types must be valid
- Operators must be valid
- Next puzzle IDs must exist
- Value formats must match operators
{
"name": "Beginner's Logic Journey",
"description": "Learn logic puzzles step by step",
"story": {
"intro": "Welcome to your logic puzzle journey!",
"outro": "Congratulations on completing your first logic journey!",
"chapters": [
{
"id": "basics",
"title": "Logic Basics",
"description": "Start with fundamental logic concepts",
"storyText": "Let's begin with the basics of logical reasoning..."
}
]
},
"rewards": {
"completion": {
"xp": 300,
"coins": 150,
"items": ["logic_novice_badge"]
}
}
}{
"puzzleId": "puzzle-123",
"sequenceOrder": 1,
"unlockConditions": {
"previousPuzzles": ["puzzle-122"],
"minimumScore": 80,
"timeLimit": 180
},
"isCheckpoint": true,
"checkpointRewards": {
"xp": 30,
"coins": 15,
"items": ["checkpoint_1"]
}
}{
"puzzleId": "puzzle-456",
"sequenceOrder": 2,
"branchConditions": [
{
"conditionType": "score",
"operator": "gte",
"value": 90,
"nextPuzzleId": "advanced-puzzle-789"
},
{
"conditionType": "score",
"operator": "lt",
"value": 90,
"nextPuzzleId": "review-puzzle-101"
}
]
}