Visit /api/docs for the interactive Scalar API reference with all endpoints, schemas, and examples.
The OpenAPI specification is dynamically generated at /api/openapi.json and automatically uses the correct domain based on your environment.
http://localhost:5173/api # Development
https://your-domain.com/api # Production
The base URL is automatically configured via the PUBLIC_SITE_URL environment variable.
Most API endpoints require authentication. GG Requestz supports multiple authentication methods:
For web browser access, authentication is handled via session cookies:
Cookie: session=<session-token>
Cookie: basic_auth_session=<basic-auth-token>
Content-Type: application/jsonFor programmatic access, use API keys with Bearer token authentication:
Authorization: Bearer ggr_<your-api-key>
Content-Type: application/jsonCreating API Keys:
- Log in to your account
- Navigate to Admin → API Keys
- Click "Create New API Key"
- Select the appropriate scopes (permissions)
- Copy the generated key - it will only be shown once!
API Key Scopes:
games:read- Read game information and searchrequests:read- View game requestsrequests:write- Create and manage game requestswatchlist:read- View watchlistwatchlist:write- Add and remove games from watchlistuser:read- Read user profile and preferencesuser:write- Update user profile and preferencesadmin:read- Read admin data and analyticsadmin:write- Manage users, requests, and system settings*- Full access to all API endpoints
Security Best Practices:
- Store API keys securely (use environment variables, never commit to git)
- Use the minimum required scopes for each key
- Rotate keys regularly
- Revoke unused keys immediately
- Set expiration dates when possible
Returns application version and feature information.
Response:
{
"version": "1.2.2",
"name": "gg-requestz",
"environment": "production",
"buildTime": "2025-09-29T12:00:00Z",
"features": {
"oidc": true,
"basicAuth": true,
"redis": true,
"romm": true,
"typesense": false
},
"api": {
"version": "v1",
"endpoints": [
"/api/games",
"/api/auth",
"/api/search",
"/api/watchlist",
"/api/admin"
]
}
}Health check endpoint for monitoring.
Response:
{
"status": "ok",
"timestamp": "2025-09-29T12:00:00Z",
"uptime": 3600,
"version": "1.2.2"
}Basic authentication login.
Request:
Content-Type: application/x-www-form-urlencoded
username=user@example.com&password=password123Response:
{
"success": true,
"message": "Login successful",
"user": {
"id": "123",
"username": "user@example.com",
"is_admin": false
}
}Register new user account.
Request:
{
"username": "newuser@example.com",
"password": "securepassword123",
"confirmPassword": "securepassword123"
}Response:
{
"success": true,
"message": "Registration successful",
"user": {
"id": "124",
"username": "newuser@example.com",
"is_admin": false
}
}Logout current session.
Response:
{
"success": true,
"message": "Logged out successfully"
}OIDC authentication initiation.
Response: Redirects to OIDC provider login page.
OIDC authentication callback.
Query Parameters:
code(string): Authorization code from OIDC providerstate(string): Security state parameter
Search games with IGDB integration.
Query Parameters:
q(string): Search querypage(number): Page number (default: 1)per_page(number): Results per page (default: 20, max: 100)autocomplete(boolean): Return autocomplete suggestions
Autocomplete Response:
{
"success": true,
"suggestions": [
"The Legend of Zelda",
"Zelda: Breath of the Wild",
"Zelda: Tears of the Kingdom"
]
}Search Response:
{
"success": true,
"hits": [
{
"document": {
"id": "72129",
"name": "The Legend of Zelda: Breath of the Wild",
"summary": "Game description...",
"cover": {
"url": "https://images.igdb.com/igdb/image/upload/t_cover_big/co1nqg.jpg"
},
"platforms": [{ "name": "Nintendo Switch" }, { "name": "Wii U" }],
"genres": [{ "name": "Adventure" }, { "name": "Role-playing (RPG)" }],
"rating": 97.5,
"first_release_date": 1488499200
}
}
],
"found": 1,
"page": 1
}Advanced search with filters.
Request:
{
"query": "zelda",
"platforms": ["Nintendo Switch"],
"genres": ["Adventure"],
"page": 1,
"per_page": 20
}Get popular games from IGDB.
Query Parameters:
page(number): Page number (default: 1)limit(number): Results per page (default: 16)user_id(string): User ID for content filtering
Response:
{
"success": true,
"games": [
{
"igdb_id": "72129",
"title": "The Legend of Zelda: Breath of the Wild",
"cover_url": "https://images.igdb.com/igdb/image/upload/t_cover_big/co1nqg.jpg",
"rating": 97.5,
"popularity_score": 98.2,
"platforms": ["Nintendo Switch", "Wii U"],
"genres": ["Adventure", "Role-playing (RPG)"]
}
],
"hasMore": true,
"total": 1000
}Get recently released games.
Query Parameters:
page(number): Page number (default: 1)limit(number): Results per page (default: 16)user_id(string): User ID for content filtering
Response:
{
"success": true,
"games": [...],
"hasMore": true,
"total": 500
}Get detailed game information by IGDB ID.
Example: /api/games/72129
Response:
{
"success": true,
"game": {
"igdb_id": "72129",
"title": "The Legend of Zelda: Breath of the Wild",
"summary": "Step into a world of discovery...",
"cover_url": "https://images.igdb.com/igdb/image/upload/t_cover_big/co1nqg.jpg",
"screenshots": [
"https://images.igdb.com/igdb/image/upload/t_screenshot_big/sc1234.jpg"
],
"videos": [
{
"video_id": "vNuOLHNR1bw",
"name": "Official Trailer"
}
],
"platforms": ["Nintendo Switch", "Wii U"],
"genres": ["Adventure", "Role-playing (RPG)"],
"companies": ["Nintendo"],
"game_modes": ["Single player"],
"rating": 97.5,
"release_date": "2017-03-03",
"esrb_rating": "E10+",
"is_mature": false,
"is_nsfw": false,
"content_rating": "Everyone 10+: Fantasy Violence, Mild Suggestive Themes"
}
}Browse games by genre.
Example: /api/browse/genres/role-playing-rpg
Query Parameters:
page(number): Page numberlimit(number): Results per page
Response:
{
"success": true,
"genre": {
"name": "Role-playing (RPG)",
"slug": "role-playing-rpg"
},
"games": [...],
"pagination": {
"page": 1,
"hasMore": true,
"total": 2500
}
}Browse games by publisher.
Example: /api/browse/publishers/nintendo
Add game to user's watchlist.
Request:
{
"igdb_id": "72129"
}Response:
{
"success": true,
"message": "Added to watchlist"
}Remove game from watchlist.
Request:
{
"igdb_id": "72129"
}Response:
{
"success": true,
"message": "Removed from watchlist"
}Batch watchlist operations.
Request:
{
"gameIds": ["72129", "12345", "67890"],
"action": "check_status"
}Response:
{
"success": true,
"watchlistStatuses": {
"72129": true,
"12345": false,
"67890": true
}
}Check if game is in user's watchlist.
Example: /api/watchlist/status/72129
Response:
{
"success": true,
"inWatchlist": true
}Submit a new game request.
Authentication Required: Yes (API key or session)
Required Scopes: requests:write (for API keys)
Request:
{
"request_type": "game",
"title": "The Legend of Zelda: Breath of the Wild",
"igdb_id": "72129",
"platforms": ["Nintendo Switch", "Wii U"],
"priority": "medium",
"description": "Would love to have this game in the library",
"game_data": {
"title": "The Legend of Zelda: Breath of the Wild",
"summary": "Game description...",
"cover_url": "https://images.igdb.com/...",
"rating": 97.5,
"platforms": ["Nintendo Switch", "Wii U"],
"genres": ["Adventure", "RPG"]
}
}Request Types:
game- Request a new gameupdate- Request an update to existing game (includeupdate_type,new_information,existing_game)fix- Report an issue with a game (includeissue_type,affected_platform,existing_game)
Priority Levels:
low- Nice to havemedium- Would appreciate (default)high- Really want thisurgent- Critical request
Response:
{
"success": true,
"request": {
"id": 123,
"title": "The Legend of Zelda: Breath of the Wild",
"request_type": "game",
"priority": "medium",
"status": "pending",
"created_at": "2025-10-06T12:00:00Z"
}
}Remove/rescind a game request.
Request:
{
"requestId": "uuid-request-id"
}Response:
{
"success": true,
"message": "Request rescinded successfully"
}Get user's content filtering preferences.
Response:
{
"success": true,
"preferences": {
"content_filter_level": "mild",
"hide_mature_content": true,
"hide_nsfw_content": true,
"max_esrb_rating": "T",
"custom_content_blocks": ["violence", "gambling"],
"preferred_genres": ["Adventure", "RPG"],
"excluded_genres": ["Horror", "Sports"],
"apply_to_homepage": true,
"apply_to_popular": true,
"apply_to_recent": false,
"apply_to_search": true
}
}Update user preferences.
Request:
{
"content_filter_level": "strict",
"hide_mature_content": true,
"max_esrb_rating": "E10+",
"custom_content_blocks": ["violence", "drug use"]
}Response:
{
"success": true,
"message": "Preferences updated successfully"
}Direct IGDB API proxy for game data.
Query Parameters:
action(string): IGDB action (search, details, etc.)query(string): Search querylimit(number): Result limit
Advanced IGDB queries.
Request:
{
"action": "search",
"query": "zelda",
"limit": 10
}Get recently added ROMs from ROMM library.
Query Parameters:
page(number): Page numberlimit(number): Results per page
Response:
{
"success": true,
"roms": [
{
"id": "123",
"name": "Super Mario Bros.",
"platform": "NES",
"added_at": "2025-09-29T12:00:00Z"
}
],
"hasMore": true
}Cross-reference games with ROMM library.
Request:
{
"gameIds": ["72129", "12345"]
}Response:
{
"success": true,
"enrichedGames": [
{
"igdb_id": "72129",
"name": "The Legend of Zelda: Breath of the Wild",
"romm_available": true,
"romm_url": "http://romm-server/rom/123"
}
]
}Clear ROMM integration cache.
Response:
{
"success": true,
"message": "ROMM cache cleared"
}Proxy and cache external images.
Query Parameters:
url(string): Image URL to proxy
Example: /api/images/proxy?url=https://images.igdb.com/igdb/image/upload/t_cover_big/co1nqg.jpg
Response: Image binary data with appropriate headers.
Get cache statistics.
Response:
{
"success": true,
"stats": {
"redis": {
"connected": true,
"keyCount": 1250,
"memoryUsed": "15.2MB"
},
"memory": {
"keyCount": 500,
"estimatedSize": "5.1MB"
}
}
}Clear all cache data.
Response:
{
"success": true,
"message": "Cache cleared successfully"
}Clean up expired cache entries.
Query Parameters:
type(string): Cache type to clean (redis, memory, all)
Admin cache management.
Request:
{
"gameId": "72129",
"clearEsrbOnly": false
}Check service connectivity during setup.
Request:
{
"service": "igdb_api"
}Response:
{
"success": true,
"service": "igdb_api",
"status": "connected",
"details": "IGDB API accessible"
}Receive webhook notifications for external integrations.
Headers:
Content-Type: application/json
X-Webhook-Secret: <configured-secret>Request:
{
"type": "game.requested",
"title": "New Game Request",
"message": "User requested: The Legend of Zelda",
"priority": 5,
"data": {
"game_id": "72129",
"user_id": "123"
}
}Response:
{
"success": true,
"results": {
"gotify": {
"id": 456,
"message": "Notification sent"
},
"n8n": {
"status": "processed"
}
}
}All endpoints return consistent error responses:
{
"success": false,
"error": "Error message describing what went wrong",
"code": "ERROR_CODE",
"details": "Additional error context"
}UNAUTHORIZED- Authentication required or failedFORBIDDEN- Insufficient permissionsNOT_FOUND- Resource not foundVALIDATION_ERROR- Invalid request parametersRATE_LIMITED- Too many requestsSERVER_ERROR- Internal server errorSERVICE_UNAVAILABLE- External service unavailable
200- Success400- Bad Request (validation error)401- Unauthorized403- Forbidden404- Not Found429- Rate Limited500- Internal Server Error
Rate limiting is applied per endpoint (when configured):
- Authenticated users: 1000 requests/hour
- Unauthenticated: 100 requests/hour
- Admin users: 5000 requests/hour
Rate limit headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200List endpoints support pagination with consistent parameters:
Query Parameters:
page(number): Page number (starts at 1)limitorper_page(number): Items per page (max: 100)
Response Format:
{
"success": true,
"data": [...],
"pagination": {
"page": 1,
"per_page": 20,
"total": 1000,
"hasMore": true
}
}Many game endpoints support content filtering based on user preferences:
Query Parameters:
user_id(string): User ID for applying content filters
Filtering automatically applies:
- ESRB rating restrictions
- Mature content blocking
- NSFW content blocking
- Custom content blocks
- Genre exclusions
With API Key:
const API_KEY = process.env.GGR_API_KEY; // Store securely in environment variables
// Search for games
const response = await fetch(
"https://your-domain.com/api/search?q=zelda&page=1&per_page=10",
{
headers: {
Authorization: `Bearer ${API_KEY}`,
},
},
);
const data = await response.json();
// Add to watchlist
await fetch("https://your-domain.com/api/watchlist/add", {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ igdb_id: "72129" }),
});
// Get popular games
const popular = await fetch(
"https://your-domain.com/api/games/popular?limit=20",
{
headers: {
Authorization: `Bearer ${API_KEY}`,
},
},
);
const games = await popular.json();With Session Cookies (Browser):
// Search for games
const response = await fetch("/api/search?q=zelda&page=1&per_page=10");
const data = await response.json();
// Add to watchlist
await fetch("/api/watchlist/add", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ igdb_id: "72129" }),
});With API Key:
# Store your API key
export GGR_API_KEY="ggr_your_api_key_here"
# Get game details
curl -H "Authorization: Bearer $GGR_API_KEY" \
"https://your-domain.com/api/games/72129"
# Search for games
curl -H "Authorization: Bearer $GGR_API_KEY" \
"https://your-domain.com/api/search?q=zelda"
# Add to watchlist
curl -X POST \
-H "Authorization: Bearer $GGR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"igdb_id":"72129"}' \
"https://your-domain.com/api/watchlist/add"
# Get popular games with filtering
curl -H "Authorization: Bearer $GGR_API_KEY" \
"https://your-domain.com/api/games/popular?page=1&limit=20"With Session Cookie:
# Get game details
curl "https://your-domain.com/api/games/72129"
# Search with authentication
curl -H "Cookie: session=your-token" \
"https://your-domain.com/api/search?q=zelda"
# Add to watchlist
curl -X POST \
-H "Content-Type: application/json" \
-H "Cookie: session=your-token" \
-d '{"igdb_id":"72129"}' \
"https://your-domain.com/api/watchlist/add"With API Key:
import requests
import os
# Load API key from environment
API_KEY = os.getenv('GGR_API_KEY')
BASE_URL = 'https://your-domain.com/api'
# Create session with auth header
session = requests.Session()
session.headers.update({
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
})
# Search for games
response = session.get(f'{BASE_URL}/search', params={
'q': 'zelda',
'page': 1,
'per_page': 10
})
games = response.json()
# Add to watchlist
response = session.post(f'{BASE_URL}/watchlist/add',
json={'igdb_id': '72129'})
result = response.json()
# Get popular games
response = session.get(f'{BASE_URL}/games/popular', params={
'page': 1,
'limit': 20
})
popular_games = response.json()
# Get game details
response = session.get(f'{BASE_URL}/games/72129')
game = response.json()With Session Cookie:
import requests
# Search for games
response = requests.get('https://your-domain.com/api/search', {
'q': 'zelda',
'page': 1,
'per_page': 10
})
games = response.json()
# Add to watchlist with session
session = requests.Session()
session.cookies.set('session', 'your-session-token')
session.post('https://your-domain.com/api/watchlist/add',
json={'igdb_id': '72129'})Current API version: v1
Version information available at /api/version
Future versions will be available at /api/v2/... with backwards compatibility maintained for v1.
GG Requestz integrates with:
- IGDB API - Game data and search
- ROMM - Personal ROM library management
- Gotify - Push notifications
- n8n - Workflow automation
- Redis - Caching and session storage
See Integration Guide for detailed setup instructions.