Server & admin
HTTP API
The control-plane endpoints and the reconciliation-friendly conventions behind them.
The server exposes a small HTTP API under /api. Tunnel mutations follow
reconciliation-friendly conventions so the API is safe to drive from retrying clients and
IaC tooling.
Tunnel endpoints
| Method & path | Purpose |
|---|---|
PUT /api/tunnels/{slug} | Create or update a tunnel (idempotent upsert). |
GET /api/tunnels/{slug} | Read a single tunnel. |
GET /api/tunnels/ | List the caller's tunnels. |
DELETE /api/tunnels/{slug} | Remove a tunnel (idempotent). |
POST /api/tunnels/{slug}:rotate-connection-token | Issue a fresh connection token, invalidating the previous one. |
Supporting endpoints include GET /api/meta (build info), POST /api/keys (issue an API
key — OIDC only), and health probes at /health/live and /health/ready.
Conventions
- Idempotent upsert —
PUTcarries the full desired spec; sending the same body twice yields the same state. Responses include achangedflag so callers can tell created from updated from no-op. - Spec / status / metadata split — responses separate the user-controlled
spec, the server-observedstatus, andmetadata(slug, timestamps, etag). - ETags &
If-Match— optimistic concurrency: clients may gate writes on anETag. The etag is computed from the spec only, so status changes don't invalidate it. - Idempotent delete —
DELETEreturns success whether or not the tunnel existed; the desired end-state ("absent") is reached either way.
PUT /api/tunnels/myapp
Content-Type: application/json
{ "targetPort": 8080, "enabled": true }Authentication
All /api/tunnels endpoints require a valid OIDC bearer token or an API key with the
appropriate permission. See Authentication.
The internal FRP plugin endpoint (/api/internal/frp) is not part of the public surface
and is protected by a separate shared-secret scheme used only by the trusted edge.