> ## Documentation Index
> Fetch the complete documentation index at: https://help.tutorbloc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Overview

> How the API is structured, versioned, and authenticated

To see which endpoints the Vue client actually calls (and how), see [Frontend API Integration](/frontend/api-integration).

<Card title="Interactive API Route Map" icon="diagram-project" href="https://mercurius-saad.github.io/tutorbloc-docs/">
  Searchable, filterable diagram of all 150+ routes, controllers, and middleware — current API, legacy v1, and web routes.
</Card>

## Base URLs

| Environment    | URL                              |
| -------------- | -------------------------------- |
| Local (Docker) | `http://localhost/api`           |
| Staging        | Configured via `APP_URL` env var |
| Production     | Configured via `APP_URL` env var |

## API versions

Two API versions coexist:

| Version   | Prefix      | Route file              | Controller namespace            |
| --------- | ----------- | ----------------------- | ------------------------------- |
| Current   | `/api/*`    | `routes/api.php`        | `tutorbloc\Http\Controllers`    |
| Legacy v1 | `/api/v1/*` | `routes/legacy-api.php` | `tutorbloc\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:

| Middleware | Header/param                         | Description                                                      |
| ---------- | ------------------------------------ | ---------------------------------------------------------------- |
| `auth:api` | `Authorization: Bearer {token}`      | Standard token auth via Redis guard                              |
| `web.api`  | Token, signed URL, or `secret` param | Hybrid auth (see [Authentication](/architecture/authentication)) |
| `internal` | Requires `auth:api` + role\_id=200   | Admin-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:

```json theme={null}
{
  "message": "Error description",
  "details": { ... },
  "exception": "ClassName",
  "trace": [...]
}
```

<Note>
  `exception` and `trace` fields are only included when `APP_DEBUG=true`.
</Note>

## 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`.
