Panel API

Automate Herne from scripts, CI pipelines, and agents with capability-scoped bearer tokens — the same rules and limits as the panel itself.

What the Panel API Is

The Panel API exposes the same capabilities as the browser panel to machine callers: CI pipelines, CLI tooling, operator scripts, AI agents, and third-party integrations. It is a second transport over the same orchestration layer — a token never grants more than its owning user can do in the panel, and tenant scoping, plan limits, role checks, and policies apply identically.

The API lives under /panel/api as a stateless bearer-token surface (no session, no CSRF). It is a management API for trusted operators of this installation, not a public hosting API: there is no anonymous signup and no self-service token issuance.

Creating a Token

Tokens are created from the panel UI only — there is no artisan command and no API endpoint for token management.

  1. Go to Panel → API Tokens.
  2. Enter a name (e.g. ci-deploy) and tick the capabilities the caller needs. Each group has a Select all toggle, and one above the list selects every capability at once.
  3. Click Create Token. The plain token (hrn_ followed by 64 random characters) is shown exactly once — copy it immediately. Only its SHA-256 hash is stored.

The screen hands you both client keys together, ready to paste into your caller's .env file or CI secret store:

HERNE_API_URL=https://your-server.example/panel/api
HERNE_API_TOKEN=hrn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

A lost token cannot be recovered or re-displayed. Revoke it and create a new one instead. Editing a token changes its name and capabilities only — there is no secret rotation.

Capability Groups

Capabilities are flat dotted resource.verb strings, grouped by power:

  • Default — read surfaces plus everyday automation (sites.read, deploy.run, backups.read, me.read, …).
  • Advanced — opt-in writes (sites.write, databases.write, env.read/env.write, artisan.run, …). env.read is deliberately write-tier: site .env files contain credentials.
  • Destructive — deletes and shell access, deliberately separated (sites.delete, databases.delete, shell.run, …). Reads never mutate, writes never imply deletes, and no delete cascades.
  • Admin — admin-role-gated surfaces (admin.users.read, admin.firewall.read, …). Only admins can grant these, and the owner must still hold the admin role at request time.

Using a Token

Send the token in the Authorization header — bearer only, no query-parameter or cookie fallback:

GET /panel/api HTTP/1.1
Host: your-server.example
Accept: application/json
Authorization: Bearer hrn_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Or with curl:

curl -H "Authorization: Bearer $HERNE_API_TOKEN" $HERNE_API_URL/me

GET /panel/api is the discovery endpoint: without a token it returns public-safe bootstrap JSON; with a token it also links the resources your capabilities can reach.

Responses

Success responses are ok-first flat JSON with domain keys at the top level:

{"ok": true, "site": {"slug": "example-com", "domain": "example.com"}}

Errors share the shape, add a stable machine code, and always carry self-discovery links:

{
  "ok": false,
  "code": "missing_capability",
  "message": "This token does not have the sites.write capability.",
  "api_discovery_url": "/panel/api",
  "openapi_url": "/panel/api/openapi.json"
}

Status usage: 200 read/update, 201 create, 401 missing/invalid/revoked token, 403 missing capability or failing policy, 404 unknown or foreign resource, 422 validation, 429 rate limited. Validation errors list errors[] as {path, message} objects.

Rate Limits

The API allows 120 requests per minute keyed on ip|token. Expensive endpoints carry the panel's tighter per-route throttles on top (deploys 10/min, restores 5/min, artisan 20/min, shell 60/min, panel updates 5/min).

Security Notes

  • The plain token is shown once at creation and never stored — only the SHA-256 hash persists.
  • Revoking a token rejects its requests immediately; the row is kept for auditing. Deleting removes the row and its activity history.
  • Admin capabilities are re-checked at request time: a role revoked after token issuance immediately disables them.
  • shell.run is never part of any default set — it must be selected deliberately and runs through the same isolated per-site shell boundary as the panel terminal.
  • Each token records its latest activity (method, path, allowed/denied, IP) — visible on the API Tokens screen. Request bodies and token material are never logged.

Coverage

Every action the panel offers has an API endpoint, including domain aliases and the external redirect, the Laravel runtime conversion, disk-usage refresh, log truncation, per-database dumps, backup size estimates, database browsing, invoices, the help topics, and your own profile. Three things stay panel-only by design: API token management itself, webmail, and the authentication flow (login, registration, password reset, email verification). The setup wizard has no endpoint of its own — each of its steps is a separate API primitive.

OpenAPI

A runtime-generated OpenAPI 3.1 document is available at GET /panel/api/openapi.json (token required). Point your client generator or agent tooling at it for the full endpoint and schema surface.