A modern and performant REST API for Nintendo game library data. Access game information, media assets, screenshots, and comprehensive statistics across Nintendo platforms.
- 🎮 Complete Nintendo Switch game database
- 🎮 Complete Nintendo 3DS game database
- 🖼️ Game icons, banners, and screenshots
- 🌍 Multi-language support (11 languages for Switch)
- 📊 Comprehensive statistics
- 🔄 Automatic daily synchronization with TitleDB
- 🚀 Fast and lightweight
The API is accessible at your deployment URL. All endpoints support trailing slashes.
GET /nx/:tid?lang=enParameters:
tid(required) - 16-character hexadecimal Title IDlang(optional) - Language code, default:en- Available:
en,ja,es,de,fr,nl,pt,it,zh,ko,ru
- Available:
fields(optional) - Comma-separated list of fields to include. Always includesid.- Example:
name,description,publisher
- Example:
Example Requests:
# Full response
GET /nx/01007EF00011E000?lang=fr
# Only specific fields
GET /nx/01007EF00011E000?fields=name,description
GET /nx/01007EF00011E000?fields=description
GET /nx/01007EF00011E000?fields=name,publisher,releaseDate,icon
# Combine parameters
GET /nx/01007EF00011E000?lang=fr&fields=name,description,introExample Response:
{
"description": "Full game description...",
"id": "01007EF00011E000",
"name": "The Legend of Zelda™: Breath of the Wild",
"publisher": "Nintendo",
"releaseDate": "2017-03-03",
"version": 196608,
"category": ["Adventure", "Action", "RPG"],
"developer": "Nintendo EPD",
"intro": "Short introduction...",
"isDemo": false,
"languages": ["ja", "en", "es", "fr", "de", "it", "nl", "ru", "ko", "zh"],
"nsuId": 70010000000025,
"numberOfPlayers": 1,
"ratingContent": ["Fantasy Violence", "Mild Suggestive Themes"],
"region": "US",
"rightsId": "01007EF00011E0000000000000000000",
"console": "nx",
"type": "base",
"icon": "https://api.nlib.cc/nx/01007EF00011E000/icon",
"banner": "https://api.nlib.cc/nx/01007EF00011E000/banner",
"screens": {
"count": 8,
"screenshots": [
"https://api.nlib.cc/nx/01007EF00011E000/screen/1",
"https://api.nlib.cc/nx/01007EF00011E000/screen/2",
"https://api.nlib.cc/nx/01007EF00011E000/screen/3"
]
}
}Example Filtered Response:
GET /nx/01007EF00011E000?fields=name,description{
"id": "01007EF00011E000",
"name": "The Legend of Zelda™: Breath of the Wild",
"description": "Full game description..."
}Notes:
- Media URLs (
icon,banner,screens) are only included if the corresponding media files are available - Use the
fieldsparameter to request only specific data and reduce response size - The
idfield is always included in the response - SQL queries are optimized to select only requested fields
- Media checks (filesystem operations) are skipped if not requested
Performance Benefits:
| Request | Response Size | SQL Complexity | Media Checks |
|---|---|---|---|
| Full response | 2-5 KB | All fields + JOIN | 3 file checks |
?fields=name,publisher |
~100 bytes | 2 fields only | None |
?fields=description |
~1-3 KB | 1 field + JOIN | None |
?fields=name,icon |
~200 bytes | 1 field only | Icon only |
Example optimization:
# Before: Full response (2.5 KB, 15ms)
GET /nx/01007EF00011E000
# After: Only what you need (150 bytes, 3ms)
GET /nx/01007EF00011E000?fields=name,publisherGET /nx/:tid/icon/:width?/:height?Parameters:
width(optional) - Size in pixels (30-4096). Automatically rounded to nearest 10.height(optional) - Must equal width if provided. Icons are always square.
Returns the game icon in JPEG format. If no size is specified, returns the original image.
Examples:
GET /nx/01007EF00011E000/icon # Original size
GET /nx/01007EF00011E000/icon/32 # 30x30 (rounded)
GET /nx/01007EF00011E000/icon/64 # 60x60 (rounded)
GET /nx/01007EF00011E000/icon/256 # 260x260 (rounded)
GET /nx/01007EF00011E000/icon/256/256 # 260x260 (explicit)
GET /nx/01007EF00011E000/icon/512/512 # 510x510 (rounded)
GET /nx/01007EF00011E000/icon/1024 # 1020x1020 (rounded)Notes:
- Icons are always square
- Sizes are automatically rounded to the nearest 10 pixels for cache optimization
- Minimum size: 30 pixels
- Both
/icon/256and/icon/256/256produce identical results - Response header
X-Size-Roundedshows the actual size served (e.g.,64->60)
GET /nx/:tid/banner/:size?
GET /nx/:tid/banner/:width/:heightParameters:
size(optional) - Banner size shorthand- Shortcuts:
240/240p,360/360p,480/480p,540/540p,720/720p,1080/1080p - Widths:
426,640,854,960,1280,1920 - Default: 1920x1080 (1080p)
- Shortcuts:
width(optional) - Custom width in pixels (100-1920)height(optional) - Custom height in pixels (100-1080)
Returns the game banner in JPEG format.
Examples (Shortcuts):
GET /nx/01007EF00011E000/banner # 1920x1080 (default)
GET /nx/01007EF00011E000/banner/1080p # 1920x1080
GET /nx/01007EF00011E000/banner/720p # 1280x720
GET /nx/01007EF00011E000/banner/540p # 960x540
GET /nx/01007EF00011E000/banner/480p # 854x480
GET /nx/01007EF00011E000/banner/360p # 640x360
GET /nx/01007EF00011E000/banner/240p # 426x240
GET /nx/01007EF00011E000/banner/1920 # 1920x1080
GET /nx/01007EF00011E000/banner/426 # 426x240Examples (Custom dimensions):
GET /nx/01007EF00011E000/banner/1280/720 # Custom 1280x720
GET /nx/01007EF00011E000/banner/1920/1080 # Custom 1920x1080
GET /nx/01007EF00011E000/banner/800/450 # Custom 800x450
GET /nx/01007EF00011E000/banner/640/360 # Custom 640x360GET /nx/:tid/screen/:indexParameters:
index(required) - Screenshot index (starts at 1)
Returns a specific screenshot in JPEG format.
GET /nx/:tid/screensExample Response:
{
"count": 8,
"screenshots": [
"https://api.nlib.cc/nx/0100ABC001234000/screen/1",
"https://api.nlib.cc/nx/0100ABC001234000/screen/2",
"https://api.nlib.cc/nx/0100ABC001234000/screen/3"
]
}Note: Screenshot URLs are dynamically generated based on the API domain.
GET /nx/statsGET /ctr/statsExample Response:
{
"total": 5844,
"categories": {
"base": 3515,
"dlc": 0,
"dsiware": 1202,
"updates": 477,
"videos": 27,
"virtual-console": 623
}
}GET /ctr/category/:categoryParameters:
category(required) - Category name:base,dlc,dsiware,extras,themes,updates,videos,virtual-console
Example Response:
{
"category": "base",
"count": 3515,
"titles": [
"0004000000030000",
"0004000000030100",
"0004000000030200"
]
}GET /ctr/:tid?fields=name,descriptionParameters:
tid(required) - 16-character hexadecimal Title IDfields(optional) - Comma-separated list of fields to include
Example Response:
{
"tid": "0004000000030000",
"uid": "50010000009504",
"name": "新・光神話 パルテナの鏡",
"formal_name": "新・光神話 パルテナの鏡",
"description": "冥府軍と、飛べない天使ピットの壮大な戦いを描いたシングルプレイ。",
"release_date_on_eshop": "2013-10-31",
"product_code": "CTR-N-AKDJ",
"platform_name": "3DSカード/ダウンロードソフト",
"region": "Japan",
"genres": ["アクション", "シューティング"],
"features": ["インターネット対応", "3D映像対応"],
"languages": ["日本語"],
"rating_system": {"name": "CERO", "age": "12"},
"version": "v0.2.0",
"media": {
"banner": "http://api.ghseshop.cc/ctr/0004000000030000/banner",
"icon": "http://api.ghseshop.cc/ctr/0004000000030000/icon",
"screenshots": {
"compiled": ["http://api.ghseshop.cc/ctr/0004000000030000/screen/1"],
"uncompiled": {
"upper": ["http://api.ghseshop.cc/ctr/0004000000030000/screen_u/1/u"],
"lower": ["http://api.ghseshop.cc/ctr/0004000000030000/screen_u/1/l"]
}
},
"thumbnails": ["http://api.ghseshop.cc/ctr/0004000000030000/thumb/1"]
}
}GET /ctr/:tid/meta/:metaParameters:
tid(required) - 16-character hexadecimal Title IDmeta(required) - Metadata field name (e.g.,name,description,release_date_on_eshop)
GET /ctr/:tid/media # All media URLs
GET /ctr/:tid/icon # Icon image
GET /ctr/:tid/banner # Banner image
GET /ctr/:tid/screens # List compiled screenshots
GET /ctr/:tid/screen/:num # Compiled screenshot
GET /ctr/:tid/screen_u # List uncompiled screenshots
GET /ctr/:tid/screen_u/:num/:screen # Uncompiled screenshot (u/l)
GET /ctr/:tid/thumbs # List thumbnails
GET /ctr/:tid/thumb/:num # Thumbnail imageNotes:
- All images are served in JPEG format
- Uncompiled screenshots use
ufor upper screen andlfor lower screen - Media files are stored in
media/ctr/[category]/[tid]/directory structure
GET /uptimeReturns server status and uptime information.
Main table storing game information.
| Column | Type | Description |
|---|---|---|
| tid | VARCHAR(16) | Title ID (Primary Key) |
| name | TEXT | Game name |
| publisher | TEXT | Publisher name |
| developer | TEXT | Developer name |
| release_date | VARCHAR(10) | Release date (YYYY-MM-DD) |
| category | TEXT | Categories (JSON array) |
| languages | TEXT | Supported languages (JSON array) |
| nsu_id | BIGINT | Nintendo eShop ID |
| number_of_players | INTEGER | Number of players |
| rating_content | TEXT | Rating content (JSON array) |
| rights_id | VARCHAR(32) | Rights ID |
| region | VARCHAR(10) | Region code |
| is_demo | INTEGER | Is demo (0/1) |
| console | VARCHAR(10) | Console identifier (default: 'nx') |
| type | VARCHAR(20) | Game type (base/update/dlc) |
| version | INTEGER | Version number |
| updated_at | TIMESTAMP | Last update timestamp |
Language-specific tables for game descriptions (11 tables: en, ja, es, de, fr, nl, pt, it, zh, ko, ru).
| Column | Type | Description |
|---|---|---|
| tid | VARCHAR(16) | Title ID (Primary Key, Foreign Key) |
| intro | TEXT | Short introduction |
| description | TEXT | Full description |
Main table storing Nintendo 3DS game information.
| Column | Type | Description |
|---|---|---|
| tid | VARCHAR(16) | Title ID (Primary Key) |
| uid | VARCHAR(32) | Unique ID |
| name | TEXT | Game name |
| formal_name | TEXT | Formal game name |
| description | TEXT | Game description |
| release_date_on_eshop | VARCHAR(10) | Release date on eShop (YYYY-MM-DD) |
| product_code | VARCHAR(32) | Product code |
| platform_name | TEXT | Platform name |
| region | VARCHAR(50) | Region |
| genres | TEXT | Genres (JSON array) |
| features | TEXT | Features (JSON array) |
| languages | TEXT | Supported languages (JSON array) |
| rating_system | TEXT | Rating system (JSON object) |
| version | VARCHAR(20) | Version |
| disclaimer | TEXT | Disclaimer text |
| descriptors | TEXT | Descriptors (JSON array) |
| category | VARCHAR(50) | Category (base/dlc/dsiware/etc.) |
| updated_at | TIMESTAMP | Last update timestamp |
Tracks synchronization history.
| Column | Type | Description |
|---|---|---|
| id | SERIAL | Auto-increment ID (Primary Key) |
| synced_at | TIMESTAMP | Sync timestamp |
| games_count | INTEGER | Number of games synced |
| status | VARCHAR(50) | Sync status |
| source | VARCHAR(100) | Sync source |
The API uses a two-stage synchronization system:
Source: https://nx-missing.ghostland.at/data/working.txt
- Downloads list of all Nintendo Switch Title IDs
- Indexes base games (TIDs starting with
01and ending with000) - Creates database entries with TID only
Source: https://raw.githubusercontent.com/blawar/titledb/refs/heads/master/
- Downloads game metadata from multiple regions
- Enriches existing TIDs with detailed information
- Supports 11 languages
- Never overwrites existing data - preserves data quality
- Existing (non-null) data is never overwritten
- US.en is processed first for English content
- Multiple regions provide data redundancy
- Node.js 18+
- PostgreSQL 12+
- Create PostgreSQL database:
# Connect to PostgreSQL
psql -U postgres
# Create database and user
CREATE DATABASE nlib_api;
CREATE USER nlib_user WITH PASSWORD 'your_secure_password';
GRANT ALL PRIVILEGES ON DATABASE nlib_api TO nlib_user;
\q- Create tables:
# Execute the schema file
psql -h localhost -U nlib_user -d nlib_api -f database-schema.sql# Clone the repository
git clone https://github.com/ghost-land/Nlib-API.git
cd Nlib-API
# Install dependencies
npm install
# Create .env file
cp .env.example .env
# Edit .env with your database credentials
# Start the server
npm startThe server will start on port 3000 by default (configurable via PORT environment variable).
Copy .env.example to .env and configure your database credentials:
cp .env.example .envThen edit .env with your PostgreSQL connection details.
# Run in development mode
npm start
# Enable debug logs
# Add DB_DEBUG=true to your .env fileMedia files are organized by platform:
media/
├── nx/
│ └── [tid]/
│ ├── icon
│ ├── banner
│ ├── screens/
│ │ ├── screen_1
│ │ ├── screen_2
│ │ └── …
│ └── cache/
└── ctr/
└── [category]/
└── [tid]/
├── icon
├── banner
├── top_image
├── screen/
│ ├── 1
│ ├── 2
│ └── …
├── screen_u/
│ ├── 1_u
│ ├── 1_l
│ ├── 2_u
│ ├── 2_l
│ └── …
└── thumb/
├── 1
├── 2
└── …
-
All media assets must be stored without file extensions; only the base name described above should exist on disk.
-
Images are expected in JPEG format (original files can be JPEG; converted assets are served as JPEG by the API).
-
Nintendo Switch: Metadata in PostgreSQL, media in
media/nx/[tid]/ -
Nintendo 3DS: Metadata in PostgreSQL (table
ctr), media inmedia/ctr/[category]/[tid]/
- All Title IDs are automatically converted to uppercase
- Endpoints can be called with or without trailing slashes
- All images are served in JPEG format
- Nintendo Switch:
- Icons support optional resizing (30-4096 pixels, rounded to nearest 10) and are always square
- Banners support multiple sizes: 240p, 360p, 480p, 540p, 720p, 1080p
- Banners support custom dimensions:
/banner/:width/:height(100-1920 x 100-1080) - Resized images are cached on disk for optimal performance
- Nintendo 3DS:
- Screenshots are available in compiled and uncompiled formats
- Uncompiled screenshots separate upper (
u) and lower (l) screens
- Screenshot URLs are generated dynamically based on the API domain
- Database synchronization runs automatically
- API responses use standard HTTP status codes (200, 404, 500)
This project is licensed under the GPL-3.0 License - see the LICENSE file for details.
- Game data sourced from TitleDB
- Nintendo Switch Title IDs from nx-missing
Contributions are welcome! Please feel free to submit a Pull Request.