Initial commit: nick docs
This commit is contained in:
173
03 - API Reference/API Overview.md
Normal file
173
03 - API Reference/API Overview.md
Normal file
@@ -0,0 +1,173 @@
|
||||
---
|
||||
title: API Overview
|
||||
tags: [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`](../../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:
|
||||
|
||||
- [[Authentication API]] - register/login/passkeys/Google OAuth
|
||||
- [[User API]] - profile, wallet, admin user management
|
||||
- [[Marketplace API]] - purchase requests, seller offers, templates, shop, reviews
|
||||
- [[Payment API]] - SHKeeper, Web3, DePay, payouts
|
||||
- [[Chat API]] - conversations and messages
|
||||
- [[Notification API]] - in-app notifications
|
||||
- [[Dispute API]] - dispute resolution
|
||||
- [[Blog API]] - blog posts (admin-managed)
|
||||
- [[Admin API]] - user management, data cleanup, manual ops
|
||||
- [[Points API]] - loyalty points, levels, referrals
|
||||
- [[AI API]] - OpenAI-backed text endpoints
|
||||
- [[File API]] - upload, delete, serve
|
||||
- [[Socket Events]] - real-time events
|
||||
- [[Error Codes]] - status mapping and error shape
|
||||
|
||||
## 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`](../../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`](../../backend/src/shared/utils/response-handler.ts). Successful responses look like:
|
||||
|
||||
```json
|
||||
{
|
||||
"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:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [ /* items */ ],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 20,
|
||||
"total": 137,
|
||||
"totalPages": 7,
|
||||
"hasMore": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Error responses use the same envelope with `success: false`:
|
||||
|
||||
```json
|
||||
{
|
||||
"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`](../../backend/src/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`:
|
||||
|
||||
```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.
|
||||
Reference in New Issue
Block a user