API Overview

The eTeamups Platform exposes a RESTful API through an Nginx reverse-proxy gateway. All service endpoints are reachable through a single base URL, with path prefixes routing requests to the appropriate microservice.

Base URL

Environment Base URL
Production https://api.zeswa.com
Local development https://localhost:18443

Every service is mounted at a top-level path prefix:

Prefix Service Internal Port
/auth Auth Service 9000
/profile Profile Service 9100
/organisation Organisation Service 9107
/media Media Service 9102
/evaluation Evaluation Service 9103

Nginx strips the prefix before forwarding the request. For example, a request to https://api.zeswa.com/auth/login is forwarded to the Auth Service as POST /login.

Authentication

Most endpoints require a valid JSON Web Token (JWT) issued by the Auth Service. Include the token in the Authorization header:

Authorization: Bearer <accessToken>

Token lifecycle

  1. Login – Call POST /auth/login with emailAddress and codeChallenge to receive an initial accessToken and refreshToken.
  2. Verify – Call POST /auth/verify with the OTP sent to the user’s email and the codeVerifier (PKCE). After successful verification the token is fully activated.
  3. Refresh – Call POST /auth/token with a valid refreshToken to obtain a new token pair before the access token expires.

If the Authorization header is missing, the API returns 401 Unauthorized. If the token is present but invalid or expired, the API returns 403 Forbidden.

Common Response Format

Successful responses return a JSON body with the relevant resource data. List endpoints typically return an array, while single-resource endpoints return an object.

{
  "statusCode": 200,
  "data": { ... }
}

Error Handling

Errors are returned using the Boom error format, which provides a consistent structure across all services:

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Descriptive error message"
}

Standard HTTP status codes

Code Meaning
200 Success
201 Resource created
400 Bad request – validation failed or missing required fields
401 Unauthorized – missing Authorization header
403 Forbidden – invalid or expired token
404 Resource not found
409 Conflict – duplicate resource
429 Too Many Requests – rate limit exceeded
500 Internal server error

Request Validation

All request bodies are validated with Zod schemas on the server side. If validation fails, the response will be a 400 Bad Request with a message field describing which fields failed and why.

Example validation error:

{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "\"emailAddress\" must be a valid email"
}

Rate Limiting

Nginx enforces two rate-limiting zones:

Zone Rate Applied to
login 5 requests per minute per IP /auth endpoints
api 10 requests per second per IP /profile, /organisation, /media endpoints

Both zones allow a burst buffer (burst=10 for login, burst=20 for API) with nodelay, meaning burst requests are served immediately but the average rate is enforced over time. Exceeding the limit returns HTTP 429.

CORS Configuration

Cross-Origin Resource Sharing headers are managed at the application level by each microservice. Requests from allowed origins will receive appropriate Access-Control-Allow-Origin, Access-Control-Allow-Methods, and Access-Control-Allow-Headers response headers.

Health Check Endpoints

Every service exposes two utility endpoints that do not require authentication:

Endpoint Description
GET /health Returns a simple health status. Used by Docker health checks and monitoring.
GET /_ping Lightweight liveness probe.

Through the gateway these become /auth/health, /profile/health, /organisation/health, and /media/health.

OpenAPI Specification

A machine-readable OpenAPI 3.0.3 specification that covers all services is maintained in the repository:

  • YAML: swagger/zeswa-hub-open-api.yaml
  • JSON: swagger/zeswa-hub-open-api.json

The specification is auto-generated from Express routers. Import either file into tools such as Swagger UI, Postman, or Insomnia for interactive testing.

Content Type

All API endpoints accept and return application/json unless otherwise noted. The Media Service additionally accepts multipart/form-data for file uploads and serves binary image data.

Request Size Limits

  • Default body size limit: 50 MB (set in the Nginx http block).
  • Media upload limit: 100 MB (set specifically for the /media location block).