Skip to main content
TenderCheck AI exposes a JSON REST API built on Express and TypeScript. All endpoints return application/json responses. Protected routes require an authenticated session via an HttpOnly cookie or an Authorization: Bearer header — the API accepts both so the same backend serves browser clients and programmatic integrations equally.

Base URL

The frontend resolves the API origin from the VITE_API_BASE_URL environment variable. All API endpoints are prefixed with /api.
Every request path follows the pattern:
In local development, omit VITE_API_BASE_URL (or set it to an empty string) and configure your Vite dev server proxy to forward /api requests to http://localhost:3001. The frontend will then use relative paths automatically.

Authentication

Protected routes require a valid JWT supplied in one of two ways:
  • HttpOnly cookie — the token cookie set by the server on login. Sent automatically by the browser when credentials: 'include' is used.
  • Bearer token header — Authorization: Bearer <token> for environments where cookies are unreliable (native apps, server-to-server calls, cross-origin setups).
The authMiddleware checks the cookie first, then falls back to the header. See Authentication for the full flow, token lifecycle, and code examples.

Endpoint Summary

Error Format

All errors are serialised by the global error handler into a consistent JSON envelope. The error and message fields both contain the human-readable description; status is the string literal "error".
Example — 401 Unauthorized:
Example — non-operational error (production):
In development mode the error response also includes a stack field with the full stack trace to aid debugging. This field is never present in production. For non-operational errors (unexpected crashes), the error and message values are always "Something went wrong" regardless of the underlying message, to avoid leaking implementation details.

Common Status Codes

Rate Limiting

The login endpoints are protected by a sliding-window rate limiter configured in constants.ts: The limiter is applied to:
  • POST /api/auth/login
  • POST /api/auth/google/callback
When the limit is exceeded the API responds with HTTP 429 and the following body:
Standard rate-limit headers (RateLimit-*) are included in every response from these endpoints (standardHeaders: true).

File Upload Limits

File uploads are handled via multipart/form-data using Multer in-memory storage. The following limits apply globally to all upload endpoints: Uploading a file that exceeds 50 MB returns HTTP 400 with the message:
Uploading a non-PDF file returns HTTP 400 with:

CORS

Allowed origins are driven by the ALLOWED_ORIGINS environment variable on the backend — a comma-separated list of fully-qualified frontend URLs:
The following request headers are whitelisted:
  • Content-Type
  • Authorization
  • Cache-Control
  • Pragma
  • Expires
  • X-Requested-With
Credentials (cookies) are supported — the CORS configuration sets credentials: true, which means your frontend requests must include credentials: 'include'.
In production, any origin not listed in ALLOWED_ORIGINS is blocked. Requests from unlisted origins receive an HTTP error and the server logs a [CORS] Blocked origin warning. localhost and 127.0.0.1 are always permitted in non-production environments.

Authentication

Register, login, Google OAuth PKCE, JWT details, and token storage best practices.

Tender Endpoints

Analyze tender documents, validate proposals, manage your analysis history.