Skip to main content
To see which endpoints the Vue client actually calls (and how), see Frontend API Integration.

Interactive API Route Map

Searchable, filterable diagram of all 150+ routes, controllers, and middleware — current API, legacy v1, and web routes.

Base URLs

EnvironmentURL
Local (Docker)http://localhost/api
StagingConfigured via APP_URL env var
ProductionConfigured via APP_URL env var

API versions

Two API versions coexist:
VersionPrefixRoute fileController namespace
Current/api/*routes/api.phptutorbloc\Http\Controllers
Legacy v1/api/v1/*routes/legacy-api.phptutorbloc\Http\Controllers\v1
The current API also supports header-based versioning via the API-Version request header. Controllers dynamically resolve service and transformer classes based on this header.

Authentication

Three authentication modes are used across endpoints:
MiddlewareHeader/paramDescription
auth:apiAuthorization: Bearer {token}Standard token auth via Redis guard
web.apiToken, signed URL, or secret paramHybrid auth (see Authentication)
internalRequires auth:api + role_id=200Admin-only operations
(none)Public endpoint

Rate limiting

API endpoints are throttled at 300 requests per minute per client (configured in app/Http/Kernel.php).

CORS

CORS is handled by the TrustedOrigins middleware (not Laravel’s built-in CORS package):
  • Exact match: TRUSTED_ORIGINS env var — comma-separated origins
  • Substring match: WHITELISTED_ORIGINS env var — comma-separated partial origins
Returns 403 if the Origin header doesn’t match either list.

Response format

All API responses are JSON. Errors follow this structure:
{
  "message": "Error description",
  "details": { ... },
  "exception": "ClassName",
  "trace": [...]
}
exception and trace fields are only included when APP_DEBUG=true.

HTTP caching

The ETag middleware (app/Http/Middleware/API/v1/ETag.php) adds ETag-based caching for GET requests. Returns 304 Not Modified when the client’s If-None-Match header matches.

Security headers

All responses include (via SecureHeaders middleware):
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Referrer-Policy: no-referrer-when-downgrade
Headers removed: X-Powered-By, Server.