Skip to content

Repository files navigation

ImageAPI

A self-hosted random image API with an admin panel, user portal, and folder-based media catalog. Serve curated images from sfw, nsfw, and furry categories; API access is gated by per-user keys, while image URLs are public once returned.

Features

  • Random image APIGET /api/v1/image returns a random image for a category and type
  • Type discoveryGET /api/v1/types lists available types within a category
  • Public image delivery — images are served at /i/{category}/{type}/{filename}
  • User portal — request access, log in, and manage API keys from the dashboard
  • Admin panel — approve access requests, manage users, and view API keys
  • OpenAPI docs — interactive documentation at /docs (Scalar UI)
  • ALTCHA spam protection — bot-resistant access request form
  • Discord notifications — optional webhook alerts for new access requests

Prerequisites

  • Node.js 20 or later
  • MariaDB 11 (or use the included Docker Compose stack)
  • Docker and Docker Compose (optional, recommended for production)

Quick Start (Docker)

The fastest way to run the full stack (app + MariaDB):

# 1. Clone and enter the project
git clone <repo-url>
cd ImageAPI

# 2. Create and populate .env with generated secrets
cp .env.example .env
npm run generate:env

# 3. Add your media files (see Media Layout below)
mkdir -p media/sfw media/nsfw media/furry

# 4. Start the stack
npm run docker:up

The app will be available at http://localhost:3000. MariaDB is exposed on port 3307 on the host (mapped from container port 3306).

On first startup, the server runs database migrations and creates the admin account using ADMIN_EMAIL and ADMIN_PASSWORD from .env. Save the generated values printed by generate:env.

To stop the stack:

npm run docker:down

Local Development

For development without Docker, run MariaDB locally and point the app at it.

1. Install dependencies

npm install

2. Configure environment

cp .env.example .env
npm run generate:env

Edit .env for local development:

Variable Docker value Local dev value
DATABASE_HOST db localhost
DATABASE_PORT 3306 3306 (or your MariaDB port)
BASE_URL http://localhost:3000 same
MEDIA_ROOT ./media ./media

Create the database and user in MariaDB to match MARIADB_* values in .env:

CREATE DATABASE imageapi;
CREATE USER 'imageapi'@'localhost' IDENTIFIED BY 'your-password';
GRANT ALL PRIVILEGES ON imageapi.* TO 'imageapi'@'localhost';
FLUSH PRIVILEGES;

3. Build CSS

Tailwind CSS must be compiled before the UI will look correct:

npm run build:css

Re-run this after editing files in src/styles/.

4. Add media

Place image files under media/ (see Media Layout). Supported formats: .gif, .jpg, .jpeg, .png, .webp.

5. Start the server

# Development with auto-reload
npm run dev

# Production-style start
npm start

The server waits for the database, runs migrations, bootstraps the admin user, and scans the media catalog on startup.

Environment Variables

Copy .env.example to .env and fill in values. Use npm run generate:env to auto-generate secrets:

npm run generate:env          # Generate missing secrets
npm run generate:env -- --force   # Regenerate all secrets
npm run generate:env -- --stdout  # Print to stdout instead of writing .env
Variable Description
PORT HTTP port (default: 3000)
BASE_URL Public base URL used in API responses (no trailing slash)
SESSION_SECRET Secret for signing session cookies
ALTCHA_HMAC_SECRET Secret for ALTCHA challenge verification
MARIADB_ROOT_PASSWORD MariaDB root password (Docker only)
MARIADB_DATABASE Database name (default: imageapi)
MARIADB_USER Database user (default: imageapi)
MARIADB_PASSWORD Database user password
DATABASE_HOST Database hostname (db in Docker, localhost locally)
DATABASE_PORT Database port (default: 3306)
ADMIN_EMAIL Initial admin account email
ADMIN_PASSWORD Initial admin password (auto-generated if empty on first boot)
DISCORD_WEBHOOK_URL Optional Discord webhook for access request notifications
MEDIA_ROOT Path to the media directory (default: ./media)

Media Layout

Images are organized by category and type. The catalog scans subdirectories recursively:

media/
├── sfw/
│   ├── neko/
│   │   ├── image1.png
│   │   └── image2.gif
│   └── waifu/
│       └── ...
├── nsfw/
│   └── ...
└── furry/
    └── ...
  • Categories must be one of: sfw, nsfw, furry
  • Types are folder names (or nested paths) under each category, e.g. neko, blowjob/animated
  • The API type parameter maps to these folder paths

Usage

Requesting API access

  1. Visit /request-access and submit the form (protected by ALTCHA)
  2. An admin approves the request at /admin
  3. Log in at /login and copy your API key from the dashboard

API endpoints

All API routes require authentication via Authorization: Bearer <key> or X-API-Key: <key>.

Get a random image

GET /api/v1/image?category=sfw&type=neko

Response:

{
  "category": "sfw",
  "type": "neko",
  "filename": "abc123.png",
  "url": "http://localhost:3000/i/sfw/neko/abc123.png",
  "contentType": "image/png"
}

List types in a category

GET /api/v1/types?category=sfw

Response:

{
  "category": "sfw",
  "types": ["neko", "waifu"]
}

Serve an image directly (no API key required)

GET /i/sfw/neko/abc123.png

Interactive docs with try-it-out support are available at /docs.

Admin panel

Log in with the admin credentials from .env and visit /admin to:

  • Review and approve/reject access requests
  • Enable or disable user accounts
  • View user API keys

Scripts

Command Description
npm start Start the production server
npm run dev Start with file watching
npm run build:css Compile Tailwind CSS
npm run generate:env Generate .env secrets
npm run docker:up Build and start Docker Compose stack
npm run docker:down Stop Docker Compose stack

Project Structure

├── src/
│   ├── server/          # Fastify web server
│   │   ├── auth/        # Sessions, API keys, users
│   │   ├── db/          # MariaDB pool, migrations, schema
│   │   ├── media/       # Folder catalog scanner
│   │   ├── routes/      # API, pages, images, ALTCHA
│   │   └── notifications/
│   └── styles/          # Tailwind source CSS
├── views/               # Handlebars templates
├── public/              # Static assets (compiled CSS)
├── scripts/             # Utility scripts (generate-env)
├── media/               # Image files (gitignored)
├── docker-compose.yml
└── Dockerfile

License

Private — all rights reserved.

About

Curated anime & furry images on demand

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages