API & usage guide

Everything the dashboard does is available over HTTPS at https://panel.cachivo-l7.com/api/v1.

Authentication

Two credential types, both sent as Authorization: Bearer <value>.

1 — Short-lived JWT (interactive)

curl -s https://panel.cachivo-l7.com/api/v1/auth/login \
  -H 'content-type: application/json' \
  -d '{"email":"[email protected]","password":"…"}'
# -> {"access_token":"eyJ…","refresh_token":"eyJ…","token_type":"bearer"}

Access tokens last 15 minutes; refresh with POST /auth/refresh. POST /auth/logout revokes every outstanding token for the user.

2 — Long-lived API token (automation)

curl -s -X POST https://panel.cachivo-l7.com/api/v1/tokens \
  -H "authorization: Bearer $JWT" -H 'content-type: application/json' \
  -d '{"label":"ci-bot","expires_in_days":365}'
# -> {"id":3,"token":"pp_…","note":"store this now — it is not shown again"}
Tokens are stored only as a SHA-256 digest — the value cannot be recovered. Mint and revoke them in the dashboard under API Tokens, or via DELETE /tokens/{id}. A token carries exactly its owner's permissions.

Roles

RoleCan do
adminEverything: resellers, credit, PoP fleet, settings, audit, approvals
resellerOwn servers, own wallet and API tokens
Tenant isolation is enforced on every query. A request for another tenant's object returns 404 — never 403 — so object existence never leaks.

Protected servers

EndpointNotes
GET/serversList (tenant-scoped) — ?search= ?limit= ?offset=
POST/serversCreate admin · reseller
GET/servers/{id}Fetch one
POST/servers/{id}/suspendWithdraw config + park DNS
POST/servers/{id}/resumeRe-provision + re-publish
POST/servers/{id}/approveApproval gate admin
DELETE/servers/{id}Soft-delete + remove DNS
curl -s -X POST https://panel.cachivo-l7.com/api/v1/servers \
  -H "authorization: Bearer $TOKEN" -H 'content-type: application/json' \
  -d '{"origin_fqdn":"shop-origin.example.com","subdomain_label":"server33312",
       "protocol":"https","origin_port":443}'
# -> {"id":7,"assigned_subdomain":"server33312.scrubbing.top","status":"active", …}

Self-service

EndpointNotes
GET/meWho am I
GET/me/serversMy servers
GET/me/walletCredit balance + ledger reseller
GETPOSTDEL/tokensManage API tokens

Administration admin

EndpointNotes
GET/admin/overviewCounts: resellers, servers, PoP health
GETPOST/admin/resellersList / create resellers
POST/admin/resellers/{id}/creditTop up — auto-resumes suspended servers
GETPOST/admin/popsFleet list / one-click add (202 + job id)
POST/admin/pops/{id}/drainDrain from the load balancer
GET/admin/fleetLive CPU / RAM / traffic per PoP
GET/admin/pops/{id}/metricsTime-series — ?minutes= ?resolution=
GETPOST/admin/settingsgrace_days, monthly_points, auto-approve
GET/admin/auditAppend-only audit log

Errors & limits

StatusMeaning
401Unauthenticated — missing, expired or revoked credential
403Authenticated but the wrong role for this action
404Not found or not yours (existence is never leaked)
402Insufficient credit to activate or renew
409Conflict — subdomain or name already taken
422Validation error — check the detail field
429Rate limited (login is throttled per IP and per account)

All errors are returned as {"detail": "…"}.