Skip to content

Repository files navigation

ForgeAPI Platform

CI

A self-hosted API-platform starter for teams that need secure API keys, scoped access, quotas, idempotent writes, request tracing, and a typed client without assembling those primitives from scratch.

ForgeAPI is built for platform engineers, backend developers, and small teams building internal, partner, multi-tenant, or AI/tool APIs. It is also a concrete reference project for understanding how these concerns fit together.

Current status (September 2026): Early-stage reference implementation. The Todo API is the example resource; ForgeAPI is not a hosted SaaS product.

Screenshots

Framed captures of the live control-plane dashboard (current UI).

ForgeAPI usage dashboard with quota, latency, and recent Todo API requests ForgeAPI projects list with the seeded Demo Project ForgeAPI API key management with live key, scopes, rotate, and revoke ForgeAPI usage and API keys windows showing live request tracing

Why ForgeAPI

Most teams eventually need the same API foundation:

  • Give each service, tenant, or partner its own credentials.
  • Limit usage without scattering quota logic across application code.
  • Make retries safe when networks fail or clients time out.
  • Show developers how to authenticate, handle errors, and use a typed client.
  • Keep enough request context to investigate failures.

ForgeAPI packages those concerns into one runnable control plane, data plane, database, quota store, and SDK so a team can start from a working boundary instead of a blank repository.

Who should use it

ForgeAPI is a good starting point for:

  • Internal APIs shared by multiple services or teams
  • Partner and integration APIs with scoped credentials and rotation
  • Multi-tenant SaaS APIs with per-project quotas
  • AI and tool backends that need typed clients, retries, and idempotent writes

It is not the right choice yet if you need a hosted API gateway, billing-grade metering, a complete OpenAPI portal, multi-region operations, or a turnkey production deployment.

See use cases, production-readiness guidance, and the roadmap before adopting it for an external customer-facing API.

Choose your path

If you want to... Start here
Run a working API platform locally Follow the 5-minute quick start
See the SDK and retry/idempotency behavior Run pnpm demo
Understand the system boundary Read the architecture
Decide whether it fits your product Read the use cases
Plan a real deployment Read production readiness
Contribute or extend the example Read CONTRIBUTING.md

Core capabilities

Capability User value
Project-scoped API keys Give services and partners isolated credentials
Scopes and key rotation Reduce blast radius and support safe credential changes
Redis-backed quotas Apply plan limits consistently per project
Transactional idempotency Make retryable writes safe during network failures
Request IDs and logs Trace a request across client, API, and persistence
Typed zero-dependency SDK Give TypeScript consumers a fast, predictable integration path
Dashboard control plane Manage projects, keys, usage, and request activity

Detailed features

  • API key creation, revocation, expiration, and rotation
  • Separate test and live API key environments
  • SHA-256 API key hashing with a configurable server-side pepper
  • Scoped Bearer-token authentication
  • Project ownership and access control
  • Redis-backed quota enforcement
  • Daily and monthly quota windows
  • Configurable quota fail-open and fail-closed behavior
  • Cursor-based Todo API pagination
  • Transaction-safe idempotency for write requests
  • Consistent structured API errors with request IDs
  • Request logging and rate-limit response headers
  • Next.js dashboard for projects, keys, usage, and request activity
  • Typed, zero-dependency TypeScript SDK
  • PostgreSQL persistence through Prisma
  • Docker Compose development infrastructure
  • Turborepo-based monorepo workflows
  • Automated formatting, typechecking, builds, tests, and dependency auditing

Architecture

flowchart LR
    Consumer["Consumer application"] --> SDK["@mangeshraut/forge-sdk"]
    SDK --> API["Fastify REST API"]

    Dashboard["Next.js control plane"] --> PostgreSQL["PostgreSQL"]
    API --> PostgreSQL
    API --> Redis["Redis quota counters"]

    Dashboard --> Projects["Projects and API keys"]
    API --> Auth["Authentication and scopes"]
    API --> Quotas["Quota enforcement"]
    API --> Idempotency["Transactional idempotency"]
Loading

ForgeAPI is split into two logical planes:

  • Control plane: The Next.js dashboard used to manage users, projects, API keys, usage, and request logs.
  • Data plane: The Fastify REST API consumed by applications using generated API keys.

Repository structure

apps/
├── api/              Fastify REST API
├── dashboard/        Next.js control-plane dashboard
└── todo-demo/        CLI application exercising the SDK

packages/
├── auth/             Ownership and soft-delete helpers
├── config/           Shared TypeScript configuration
├── db/               Prisma client and PostgreSQL schema
├── sdk/              Typed ForgeAPI client
└── shared/           Schemas, types, plans, quotas, errors, and scopes

tests/                Cross-package SDK tests
docs/                 Architecture and design documentation
docker-compose.yml    PostgreSQL and Redis development services

Technology stack

Area Technology
Runtime Node.js 22
Package manager pnpm
Monorepo Turborepo
API Fastify 5
Dashboard Next.js 15 App Router
Authentication NextAuth
Database PostgreSQL 16
ORM Prisma 6
Quotas Redis 7 and ioredis
Validation Zod
SDK TypeScript and Fetch
Testing Vitest
CI GitHub Actions

Quick start

Prerequisites

  • Node.js 22.x
  • pnpm 9.x
  • Docker and Docker Compose

The repository includes an .nvmrc file for the expected Node.js version.

Install dependencies

git clone https://github.com/mangeshraut712/forge-api-platform.git
cd forge-api-platform

nvm install
nvm use
corepack enable
pnpm install

Configure the environment

cp .env.example .env

The development environment uses:

  • PostgreSQL on localhost:5432
  • Redis on localhost:6379
  • API on localhost:4000
  • Dashboard on localhost:3000

Start PostgreSQL and Redis

pnpm docker:up

Initialize the database

pnpm db:generate
pnpm db:push
pnpm db:seed

The seed command creates a development user, a demo project, and a live API key. The raw API key is printed once in the terminal.

Copy that key into .env:

FORGE_API_KEY=forge_live_your_key_here

Start the applications

pnpm dev

Open the dashboard at:

http://localhost:3000

The development credentials login accepts:

dev@forge.local

No password is required when AUTH_DEV_LOGIN=true.

The API is available at:

http://localhost:4000

Run applications individually when needed:

pnpm --filter @forge/api dev
pnpm --filter @forge/dashboard dev
pnpm demo

API

Public endpoints

Method Endpoint Description
GET /health Liveness check
GET /ready PostgreSQL and Redis readiness check

Todo endpoints

All /v1/* endpoints require a valid Bearer token.

Method Endpoint Scope Description
GET /v1/todos todos:read List todos with cursor pagination
GET /v1/todos/:id todos:read Retrieve one todo
POST /v1/todos todos:write Create a todo
PUT /v1/todos/:id todos:write Replace a todo
PATCH /v1/todos/:id todos:write Partially update a todo
DELETE /v1/todos/:id todos:write Delete a todo

Authentication

Authorization: Bearer forge_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

API keys are only displayed in raw form once. The API stores a hash and a visible prefix rather than the original key.

Create a todo

export FORGE_API_KEY="forge_live_your_key_here"

curl -X POST http://localhost:4000/v1/todos \
  -H "Authorization: Bearer $FORGE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: todo-example-1" \
  -d '{"title":"Ship ForgeAPI"}'

List todos

curl "http://localhost:4000/v1/todos?limit=20" \
  -H "Authorization: Bearer $FORGE_API_KEY"

Idempotency

Write requests support the Idempotency-Key header.

Retrying a request with the same key and request body replays the original response. Reusing the same key with a different request body returns a conflict response.

Idempotent write operations:

  • POST /v1/todos
  • PUT /v1/todos/:id
  • PATCH /v1/todos/:id

Rate-limit headers

API responses include quota information:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1742956800

Error format

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid API key",
    "request_id": "request-id"
  }
}

TypeScript SDK

The SDK is configured as @mangeshraut/forge-sdk.

import { createForgeClient } from "@mangeshraut/forge-sdk";

const client = createForgeClient({
  apiKey: process.env.FORGE_API_KEY!,
  baseUrl: "http://localhost:4000",
});

const created = await client.createTodo({
  title: "Ship ForgeAPI",
});

const todos = await client.listTodos({
  limit: 20,
});

await client.updateTodo(created.id, {
  completed: true,
});

await client.deleteTodo(created.id);

The SDK also provides:

  • Runtime API key format validation
  • Typed Todo operations
  • Typed API errors
  • Request ID access
  • Configurable request timeouts
  • Retry handling for safe requests
  • Idempotency-key support for writes

Plans and quotas

Plan Default limit Window
FREE 100 requests Day
DEVELOPER 10,000 requests Month
CUSTOM Configurable Day or month

Quota counters are maintained in Redis using atomic increments and expiration windows.

When Redis is unavailable, behavior is controlled by:

QUOTA_FAIL_MODE=open

Use open to prioritize availability or closed to prioritize strict quota enforcement. Closed mode responds with HTTP 503 and quota_unavailable, which is distinct from a project that has actually used its quota.

Development commands

pnpm dev                 # Start the API, dashboard, and demo
pnpm demo                # Run the end-to-end Todo SDK demo
pnpm build               # Build all packages and applications
pnpm test                # Run the test suite
pnpm typecheck           # Type-check the monorepo
pnpm lint                # Check formatting
pnpm format              # Format supported source files
pnpm db:generate         # Generate the Prisma client
pnpm db:push             # Apply the schema to the local database
pnpm db:migrate          # Create and apply a development migration
pnpm db:migrate:deploy   # Apply checked-in migrations to a deployment database
pnpm db:seed             # Seed local development data
pnpm docker:up           # Start PostgreSQL and Redis
pnpm docker:down         # Stop PostgreSQL and Redis
pnpm audit --prod        # Audit production dependencies

Running the Todo demo

Make sure the API is running and FORGE_API_KEY is configured.

pnpm --filter @forge/todo-demo dev

The demo exercises:

  • Todo listing, creation, updates, and deletion
  • Idempotency replay
  • Invalid and unknown API key handling
  • Request timeouts
  • Network retries
  • Rate-limit headers

Environment variables

Copy .env.example to .env for local development.

Important production values include:

  • A long random AUTH_SECRET
  • A separate API_KEY_HASH_PEPPER with at least 32 characters
  • Production PostgreSQL and Redis URLs
  • Explicit CORS_ORIGINS (cookie credentials are not allowed)
  • TRUST_PROXY left false unless the API sits behind a known proxy, in which case set the hop count
  • QUOTA_FAIL_MODE selected according to availability requirements (closed returns HTTP 503 quota_unavailable when Redis is down)
  • Google OAuth credentials if Google login is enabled

Never commit .env, API keys, OAuth secrets, or database credentials.

For a deployment database, set DATABASE_URL in the deployment environment and run pnpm db:migrate:deploy. The repository includes an initial Prisma migration; use pnpm db:push only for local schema prototyping.

Security model

ForgeAPI applies several security controls:

  • API keys are hashed before storage.
  • API keys are validated for environment and format.
  • API routes require explicit scopes and return insufficient_scope when a key is missing one.
  • Project resources are ownership-scoped. Todo list cursors must belong to the same project.
  • Deleted users are prevented from authenticating, including keys that were still inside a rotation grace window.
  • The dashboard rejects unverified Google emails and requires AUTH_SECRET to be at least 32 characters in production.
  • IP rate limits do not apply to /health or /ready, and TRUST_PROXY defaults to false so clients cannot spoof X-Forwarded-For.
  • Request logs store the path without the query string.
  • Request IDs are generated and returned with errors.
  • Request bodies are size-limited.
  • Idempotency records are committed with their write side effects.
  • Production key hashing requires a strong pepper.
  • Dependency vulnerabilities are checked in CI.

This repository is a reference implementation and should be threat-modeled and configured separately before production deployment.

CI

GitHub Actions runs on pushes and pull requests targeting main.

The workflow performs:

  1. Frozen dependency installation
  2. Prisma client generation
  3. Formatting checks
  4. Typechecking
  5. Builds
  6. Tests

Project status

The current implementation uses the Todo resource to demonstrate the platform lifecycle. The architecture is intended to support additional API resources, dashboard views, plans, and integrations over time. See the roadmap and production-readiness guide for the intended adoption path and current boundaries.

Contributing

See CONTRIBUTING.md for local setup, quality checks, and pull request guidance.

Security reports

Please do not report security vulnerabilities in public issues. See SECURITY.md for the responsible disclosure process.

License

MIT. See LICENSE.

Releases

Packages

Used by

Contributors

Languages