Complete reference documentation for all PixelTrivia API endpoints.
- Overview
- Authentication
- Rate Limiting
- Response Format
- Quiz Endpoints
- Game Endpoints
- Room Endpoints
- Upload Endpoints
- Error Handling
All API endpoints follow RESTful conventions and return JSON responses.
Base URL:
- Development:
http://localhost:3000/api - Production:
https://your-domain.com/api
Content Type:
Content-Type: application/json
Currently, PixelTrivia uses public endpoints with rate limiting for protection. No API keys are required for client requests.
Internal endpoints (like AI generation) use server-side API keys configured via environment variables.
All endpoints are protected by rate limiting:
| Endpoint Type | Rate Limit | Routes |
|---|---|---|
| Quiz | 30 requests/minute | /api/quiz/quick, /api/game/questions |
| AI Generation | 5 requests/minute | /api/quiz/custom, /api/quiz/advanced, /api/upload |
| Room Creation | 10 requests/5 minutes | /api/room/create |
| Standard (default) | 100 requests/minute | All other endpoints |
Rate Limit Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1706745600
Rate Limit Exceeded Response:
{
"success": false,
"error": "Rate limit exceeded. Try again in 60 seconds.",
"code": "RATE_LIMIT_EXCEEDED",
"statusCode": 429,
"meta": { "timestamp": "2026-02-03T12:00:00.000Z" }
}Status: 429 Too Many Requests
All API responses follow a consistent structure using lib/apiResponse helpers:
{
"success": true,
"data": { ... },
"message": "Operation completed successfully",
"meta": { "timestamp": "2026-02-03T12:00:00.000Z" }
}{
"success": false,
"error": "Human-readable error description",
"code": "ERROR_CODE",
"statusCode": 400,
"meta": { "timestamp": "2026-02-03T12:00:00.000Z" }
}Fetches random questions from the database for quick play mode.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
category |
string | Yes | Category to filter questions |
Example Request:
curl -X POST http://localhost:3000/api/quiz/quick \
-H "Content-Type: application/json" \
-d '{"category": "gaming"}'Success Response (200):
{
"success": true,
"data": {
"questions": [
{
"id": 1,
"question": "What game features a plumber named Mario?",
"options": ["Sonic", "Super Mario Bros", "Zelda", "Metroid"],
"correctAnswer": 1,
"category": "Gaming",
"difficulty": "easy",
"imageUrl": null
}
],
"totalQuestions": 10
},
"message": "Questions fetched successfully"
}Error Responses:
| Status | Error | Description |
|---|---|---|
| 400 | Category is required | Missing category parameter |
| 400 | Invalid category | Category must be a non-empty string |
| 404 | No questions found | No questions match the category |
| 500 | Database query failed | Database connection error |
Generates AI-powered custom quiz questions using DeepSeek.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
knowledgeLevel |
string | Yes | Player's knowledge level |
context |
string | No | Topic/context for questions |
numQuestions |
number | Yes | Number of questions (1-50) |
Knowledge Levels:
classic(default — general knowledge)college(university level)high-schoolmiddle-schoolelementary
Example Request:
curl -X POST http://localhost:3000/api/quiz/custom \
-H "Content-Type: application/json" \
-d '{
"knowledgeLevel": "college",
"context": "Space exploration and NASA missions",
"numQuestions": 10
}'Success Response (200):
{
"success": true,
"data": {
"questions": [
{
"id": "q_1",
"question": "Which spacecraft was the first to land humans on the Moon?",
"options": ["Gemini", "Apollo 11", "Skylab", "Voyager"],
"correctAnswer": 1,
"category": "Space",
"difficulty": "medium"
}
],
"metadata": {
"generatedAt": "2024-01-31T12:00:00Z",
"model": "deepseek/deepseek-chat"
}
},
"message": "Quiz generated successfully"
}Error Responses:
| Status | Error | Description |
|---|---|---|
| 400 | Knowledge level required | Missing knowledgeLevel |
| 400 | Invalid numQuestions | Must be between 1-50 |
| 429 | Rate limit exceeded | AI endpoint rate limited |
| 500 | API key not configured | Missing OpenRouter key |
| 500 | AI generation failed | DeepSeek API error |
Generates quiz questions from uploaded file content summaries.
Request Body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
filesSummary |
string | Yes | - | Summary of file content (max 3000 chars) |
numQuestions |
number | No | 10 | Questions to generate (1-20) |
format |
string | No | "short" | "short" or "long" format |
timeLimit |
number | No | 20 | Seconds per question (10-120) |
Example Request:
curl -X POST http://localhost:3000/api/quiz/advanced \
-H "Content-Type: application/json" \
-d '{
"filesSummary": "Chapter 3 covers photosynthesis, the process by which plants convert sunlight into energy. Key concepts include chlorophyll, carbon dioxide absorption, and oxygen release.",
"numQuestions": 5,
"format": "short",
"timeLimit": 30
}'Success Response (200):
{
"success": true,
"data": {
"questions": [
{
"question": "What pigment is responsible for absorbing sunlight in plants?",
"options": ["Chlorophyll", "Melanin", "Carotene", "Hemoglobin"],
"answer": "A"
}
],
"quizSettings": {
"totalQuestions": 5,
"format": "short",
"timeLimit": 30
}
},
"message": "Advanced quiz generated successfully"
}Security Features:
- Input sanitization removes markdown, HTML, and injection patterns
- Maximum 3000 character limit on file summaries
- Prompt injection detection and blocking
Error Responses:
| Status | Error | Description |
|---|---|---|
| 400 | Invalid request | Missing or invalid filesSummary |
| 400 | Content too long | Exceeds 3000 character limit |
| 429 | Rate limit exceeded | AI endpoint rate limited |
| 500 | Generation failed | AI response parsing error |
Fetches questions for multiplayer game sessions.
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
category |
string | Yes | - | Question category |
difficulty |
string | Yes | - | Difficulty level |
limit |
number | No | 10 | Max questions (1-50) |
Difficulty Levels:
elementary→ maps to "easy"middle-school→ maps to "easy"high-school→ maps to "medium"college-level→ maps to "hard"classic→ mixed difficulties
Example Request:
curl "http://localhost:3000/api/game/questions?category=science&difficulty=high-school&limit=10"Success Response (200):
{
"success": true,
"data": {
"questions": [
{
"id": 42,
"questionNumber": 1,
"question": "What is the chemical symbol for gold?",
"options": ["Au", "Ag", "Fe", "Cu"],
"correctAnswer": 0,
"category": "Science",
"difficulty": "medium",
"timeLimit": 30,
"imageUrl": null
}
],
"totalQuestions": 10,
"selectedCategory": "science",
"selectedDifficulty": "high-school",
"timeLimit": 30
},
"message": "Questions fetched successfully"
}Error Responses:
| Status | Error | Description |
|---|---|---|
| 400 | Category required | Missing category parameter |
| 400 | Difficulty required | Missing difficulty parameter |
| 400 | Invalid limit | Limit must be 1-50 |
| 404 | No questions found | No matching questions |
| 500 | Database error | Query failed |
Creates a new multiplayer game room.
Request Body: None required
Example Request:
curl -X POST http://localhost:3000/api/room/createSuccess Response (201):
{
"success": true,
"data": {
"roomCode": "A1B2C3",
"createdAt": "2024-01-31T12:00:00.000Z",
"status": "waiting"
},
"message": "Room created successfully"
}Room Code Format:
- 6 alphanumeric characters
- Uppercase letters and digits only
- Pattern:
[A-Z0-9]{6}
Error Responses:
| Status | Error | Description |
|---|---|---|
| 405 | Method not allowed | Use POST only |
| 429 | Rate limit exceeded | 10 rooms/5 minutes |
| 500 | Generation failed | Could not create unique code |
| 500 | Database error | Insert failed |
Upload documents for text extraction (used by Advanced Game mode).
Content-Type: multipart/form-data
Form Fields:
| Field | Type | Required | Description |
|---|---|---|---|
files |
File[] | Yes | One or more document files |
Supported File Types: .txt, .pdf, .docx, .md
Limits:
- Max file size: 10 MB per file
- Max files per upload: 5
- Max extracted text: 50,000 characters per file
Example Request:
curl -X POST http://localhost:3000/api/upload \
-F "files=@notes.txt" \
-F "files=@document.pdf"Success Response (200):
{
"success": true,
"data": {
"files": [
{ "name": "notes.txt", "type": "text/plain", "size": 1024, "textLength": 856 },
{ "name": "document.pdf", "type": "application/pdf", "size": 45000, "textLength": 12340 }
],
"summary": "--- notes.txt ---\nExtracted text...\n\n--- document.pdf ---\nExtracted text...",
"errors": []
}
}Partial Success Response (200):
{
"success": true,
"data": {
"files": [
{ "name": "notes.txt", "type": "text/plain", "size": 1024, "textLength": 856 }
],
"summary": "--- notes.txt ---\nExtracted text...",
"errors": [
{ "file": "broken.pdf", "reason": "Failed to parse PDF content" }
]
}
}Note: This endpoint extracts raw text from uploaded files. The extracted summary is then passed to
/api/quiz/advancedfor AI question generation.
| Code | Meaning | When Used |
|---|---|---|
| 200 | OK | Successful GET/POST |
| 201 | Created | Resource created (rooms) |
| 400 | Bad Request | Invalid parameters |
| 404 | Not Found | Resource not found |
| 405 | Method Not Allowed | Wrong HTTP method |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Internal errors |
// Validation Error
{
"success": false,
"error": "VALIDATION_ERROR",
"message": "Category must be a non-empty string",
"details": {
"field": "category",
"received": null
}
}
// Rate Limit Error
{
"success": false,
"error": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"retryAfter": 60
}
// Database Error
{
"success": false,
"error": "DATABASE_ERROR",
"message": "Failed to fetch questions from database"
}
// AI Generation Error
{
"success": false,
"error": "AI_GENERATION_FAILED",
"message": "Failed to generate quiz questions"
}# Quick Quiz
curl -X POST http://localhost:3000/api/quiz/quick \
-H "Content-Type: application/json" \
-d '{"category": "movies"}'
# Custom Quiz
curl -X POST http://localhost:3000/api/quiz/custom \
-H "Content-Type: application/json" \
-d '{"knowledgeLevel": "college", "context": "Marvel movies", "numQuestions": 5}'
# Create Room
curl -X POST http://localhost:3000/api/room/create
# Get Game Questions
curl "http://localhost:3000/api/game/questions?category=history&difficulty=classic&limit=10"// Quick Quiz
const quickQuiz = await fetch('/api/quiz/quick', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ category: 'gaming' })
});
const data = await quickQuiz.json();
// Custom Quiz
const customQuiz = await fetch('/api/quiz/custom', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
knowledgeLevel: 'college',
context: 'Quantum physics',
numQuestions: 10
})
});PixelTrivia provides client libraries in lib/:
- quickQuizApi.ts - Quick play API client
- customQuizApi.ts - Custom quiz API client
- roomApi.ts - Room management API client
- gameApi.ts - Game session API client
- multiplayerApi.ts - Multiplayer operations client
Example Usage:
import { fetchQuickQuiz } from '@/lib/quickQuizApi';
import { createRoom, joinRoom } from '@/lib/roomApi';
// Fetch quick quiz
const quiz = await fetchQuickQuiz('gaming');
// Create multiplayer room
const room = await createRoom();
console.log(`Room code: ${room.roomCode}`);Last updated: March 1, 2026