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

# HTTP API

> Use the OpenSRE backend API: health, alert intake, investigations

The OpenSRE backend serves one HTTP API (FastAPI, `gateway/http/webapp.py`). All
routes live on a single port (default `8000`). In production, always call the
API over HTTPS — deploy behind a TLS-terminating load balancer (see the
Terraform module under `infra/terraform/`).

## Authentication

The API has two auth schemes, matched to the caller:

| Routes                                   | Caller                               | Auth                                                                                                                                                                            |
| ---------------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST /alerts`, `POST /investigate`      | Machines (alert sources, schedulers) | Static bearer token: set `OPENSRE_ALERT_LISTENER_TOKEN` on the server and send `Authorization: Bearer <token>`. Without the env var, these routes only accept loopback callers. |
| `/api/*` (investigations)                | Users via the web app                | Clerk JWT: send `Authorization: Bearer <clerk-session-token>`. Records are scoped to the token's organization.                                                                  |
| `GET /health`, `GET /healthz`, `GET /ok` | Probes                               | None                                                                                                                                                                            |

## Health

```bash theme={null}
curl https://<host>/healthz          # liveness: {"status": "ok"}
curl https://<host>/health           # readiness: 503 until an LLM is configured
```

## Alert intake

Queue an alert for background investigation (returns `202`):

```bash theme={null}
curl -X POST "https://<host>/alerts" \
  -H "Authorization: Bearer $OPENSRE_ALERT_LISTENER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"text": "CPU above 90% on checkout-db", "source": "grafana"}'
```

Bodies above 1 MiB are rejected with `413`.

## Synchronous investigation

Run an investigation inline and get the report in the response (slow — the
request stays open for the full pipeline; prefer the async API behind load
balancers):

```bash theme={null}
curl -X POST "https://<host>/investigate" \
  -H "Authorization: Bearer $OPENSRE_ALERT_LISTENER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"raw_alert": {"alert_name": "HighCPU", "severity": "critical"}}'
```

## Async investigations (Clerk-authenticated)

Enqueue and poll — the pattern web clients should use. Queued investigations
are executed by a background worker in the web service; it is enabled by
setting `OPENSRE_INVESTIGATION_WORKER=1` (the Terraform deployment sets this).
Records live in Postgres when `DATABASE_URL` is set, else in process memory.
Reports are written to local disk first and uploaded to S3 when
`OPENSRE_ARTIFACTS_BUCKET` is configured.

```bash theme={null}
# Enqueue (202)
curl -X POST "https://<host>/api/investigations" \
  -H "Authorization: Bearer $CLERK_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"raw_alert": {"alert_name": "HighCPU"}, "severity": "critical",
       "workspace_id": "T0123456"}'
# → {"investigation_id": "3f6…", "status": "queued"}
# workspace_id is optional — pass the Slack workspace (team) id when the
# investigation originates from a Slack workspace.

# Poll
curl "https://<host>/api/investigations/<investigation_id>" \
  -H "Authorization: Bearer $CLERK_SESSION_TOKEN"
# → {"investigation_id": "3f6…", "status": "queued|running|completed|failed",
#    "report_s3_key": null, "report_url": null, "error": null}
```

Investigations belong to the Clerk organization in the token; reading another
organization's investigation returns `404`.

## Status codes

| Code  | Meaning                                                              |
| ----- | -------------------------------------------------------------------- |
| `202` | Accepted and queued (`/alerts`, `POST /api/investigations`)          |
| `400` | Malformed JSON or missing required fields                            |
| `401` | Missing or invalid bearer token (`/api/*`, or token-mode `/alerts`)  |
| `403` | Non-loopback caller and no `OPENSRE_ALERT_LISTENER_TOKEN` configured |
| `404` | Unknown investigation id, or one outside your organization           |
| `413` | Alert body above 1 MiB                                               |
| `503` | LLM not configured (`/health`) or investigation pipeline failure     |
