Files
nick-doc/03 - API Reference/API Overview.md
2026-05-23 20:35:34 +03:30

7.8 KiB

title, tags
title tags
API Overview
api
reference
overview

API Overview

The AMN backend is an Express.js + TypeScript service that exposes a REST API plus a Socket.IO real-time channel. Every HTTP endpoint is mounted under /api/<service>/... in backend/src/app.ts and follows a consistent response envelope, authentication scheme, and error model.

This page is the entry point for the API. See the individual service pages for endpoint details:

Base URLs

Environment Base URL
Local development http://localhost:5001/api
Staging / dev https://dev.amn.gg/api
Production https://amn.gg/api

The base port is set via PORT env var; in development it defaults to 5001. CORS is restricted to process.env.FRONTEND_URL and credentials are allowed (cors({ origin, credentials: true }) in app.ts).

Health check (not under /api): GET /health{ success, message, timestamp, environment, version }.

API discovery endpoint: GET /api → returns a map of available service prefixes.

Versioning

The API is currently un-versioned (there is no /v1 in paths). Breaking changes are communicated via release notes in the repository. The version string is exposed on /health and is sourced from package.json (process.env.npm_package_version). At the time of writing the deployed version is in the 4.x line.

Authentication

All protected endpoints use a stateless JWT in the standard HTTP Authorization header:

Authorization: Bearer <accessToken>

The token is verified by authenticateToken in backend/src/shared/middleware/auth.ts using config.jwtSecret. The decoded payload is normalised into req.user = { id, email, role } regardless of which key carried it (id, userId, _id, sub).

Tokens are issued by POST /api/auth/login, POST /api/auth/google/signin, POST /api/auth/google/signup, POST /api/auth/passkey/authenticate, and POST /api/auth/refresh-token. Refresh tokens are stored on the User document (refreshTokens array) so an admin password change wipes them and forces re-login.

Role-based access uses authorizeRoles('admin', ...) after authenticateToken. Three roles exist: buyer, seller, admin.

WebAuthn / Passkey flows live under /api/auth/passkey/* and exchange a challenge for an assertion; on success a regular JWT pair is returned (tokens.accessToken, tokens.refreshToken). See Authentication Flow for the full lifecycle.

Standard response envelope

The canonical helper is ResponseHandler in backend/src/shared/utils/response-handler.ts. Successful responses look like:

{
  "success": true,
  "message": "Success",
  "data": { /* payload */ },
  "statusCode": 200,
  "timestamp": "2026-05-23T10:00:00.000Z",
  "path": "/api/marketplace/purchase-requests",
  "method": "GET",
  "meta": { /* optional */ }
}

Paginated responses add a pagination block:

{
  "success": true,
  "data": [ /* items */ ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 137,
    "totalPages": 7,
    "hasMore": true
  }
}

Error responses use the same envelope with success: false:

{
  "success": false,
  "message": "Validation failed",
  "error": "Validation Error",
  "statusCode": 400,
  "timestamp": "2026-05-23T10:00:00.000Z",
  "path": "/api/auth/register",
  "method": "POST",
  "data": [ /* validation details */ ]
}

Caveat: not every endpoint uses ResponseHandler. Legacy routes (mainly under /api/users, /api/marketplace legacy, /api/payment/decentralized, parts of /api/payment/shkeeper) return ad-hoc shapes such as { error: string } on failure or bare objects on success. When in doubt consult the per-endpoint response section in the service pages. The error middleware in shared/middleware/errorHandler.ts covers uncaught exceptions and emits { success: false, error, statusCode, stack? }.

Pagination conventions

Most list endpoints accept ?page=<n>&limit=<n> query params:

  • page defaults to 1, 1-based.
  • limit defaults vary (20 for notifications/marketplace, 50 for user lists) and is capped (e.g. 100 for templates).
  • Server computes total, totalPages, and hasMore and returns them under pagination.
  • Some endpoints also accept offset (e.g. payment lists) as a raw skip count.

Sort parameters: list endpoints commonly accept sortBy (default createdAt) and sortOrder (asc | desc, default desc).

Common query params

Parameter Used by Meaning
search users, templates, posts Case-insensitive regex over title/name/email fields
status payments, requests, disputes, notifications Filter by entity state
role users, contacts Filter by buyer/seller/admin
isActive users, templates Boolean filter
categoryId templates, requests MongoId category filter
unreadOnly notifications Only unread items
format payment export json (default) or csv

Rate limiting

Rate limiting is currently disabled in the deployed code (app.ts logs 🔓 Rate limiting COMPLETELY DISABLED for personal use). The intended policy when re-enabled is 100 requests per 15-minute window per IP, applied per /api/* route. The Express trust proxy setting is enabled in production so the real client IP is read from X-Forwarded-For (Nginx terminator).

Redis-backed rate limiting helpers exist in src/services/redis/rateLimitService.ts and are used by sensitive auth flows (password reset, email verification) even with the global limiter off.

CORS

CORS is configured globally in app.ts:

cors({
  origin: process.env.FRONTEND_URL,
  credentials: true,
  methods: ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
})

Only the configured FRONTEND_URL may make cross-origin requests with credentials. The SHKeeper configuration endpoint (GET /api/payment/shkeeper/config) overrides this with Access-Control-Allow-Origin: * because it is consumed by the SHKeeper payment widget hosted on another domain.

Uploaded files served from /uploads/* use helmet({ crossOriginResourcePolicy: { policy: "cross-origin" } }) so they can be embedded from the frontend domain.

Real-time channel

Socket.IO runs on the same HTTP server. The frontend should connect to the API origin with credentials. Clients join rooms via join-user-room, join-request-room, join-seller-room, join-buyer-room, join-chat-room. Full catalog: Socket Events.

Standard HTTP status codes

  • 200 OK - success
  • 201 Created - resource created
  • 400 Bad Request - validation error
  • 401 Unauthorized - missing/invalid token
  • 403 Forbidden - role/ownership failure
  • 404 Not Found - resource or route missing
  • 409 Conflict - duplicate (email, review)
  • 423 Locked - account locked (auth flows)
  • 500 Internal Server Error - unhandled exception

See Error Codes for the app-specific codes returned in the error field.