API reference
Every user-facing REST route of the Telark services, grouped by resource, with the permission each one needs.
Each service serves its API under /api/v1/. The dashboard proxies them
on its own origin at /api/<service>/, so discovery's
protectionplans/prepare is
/api/discovery/api/v1/protectionplans/prepare from the browser. Paths
below are relative to /api/v1/.
Conventions
| Topic | Rule |
|---|---|
| Authentication | X-Session-Token: <token> on every route except the Public ones. No cookie, no query parameter. |
| Permission | Level on scope plus the action whose deny rule <scope>.<action>.deny withholds it. A deny rule wins over any level. See Access control. |
| Authenticated | A valid session is enough; the handler limits the call to the caller's own data. |
| Internal | Service token only (X-Service-Token). Not reachable through the dashboard proxy, which answers 404 for internal/ paths. Omitted below. |
| Unmapped route | 403. |
| Identity | Taken from the session. X-User-ID, X-Username and X-Email sent by a client are stripped. |
| Body keys | User, group, role, category and protection-plan writes refuse a key that is not exactly a field name of the record (400). |
| Body size | 413 above 1 MiB (exporter, plan and rollback routes) or 64 KiB (analyzer). |
| Outage | 503 when a service cannot resolve the caller; an outage is never answered as a denial or a grant. |
| Response | {status, operation, message, data}. Reads return id from metadata.name and flatten .status into the object. |
Applications
| Method | Path | Service | Permission |
|---|---|---|---|
GET | applications | exporter | ReadOnly on applications |
GET | applications/{name} | exporter | ReadOnly on applications |
PATCH | applications/{name} | exporter | Contributor on applications; editapplication. Display name and description only. |
POST | applications/{name}/sync | discovery | Contributor on applications; forceapplicationsync |
POST | applications/{name}/reset | discovery | Owner on applications; deleteapplication |
GET | discovery/status | discovery | ReadOnly on applications |
GET | cluster/namespaces | discovery | Authenticated; the handler requires ReadOnly on applications or on insights |
GET | cluster/namespaces/{namespace}/workloads | discovery | ReadOnly on applications |
GET | cluster/namespaces/{namespace}/resources | discovery | ReadOnly on applications |
sync and reset answer 404 for an application Telark does not hold.
The cluster/namespaces routes refuse excluded namespaces and the
release namespace (403).
Rollbacks
| Method | Path | Service | Permission |
|---|---|---|---|
GET | applications/{name}/rollbacks | exporter | ReadOnly on applications; viewapplicationsrollbacks |
GET | applications/{name}/rollbacks/{rollbackId} | exporter | ReadOnly on applications; viewapplicationsrollbacks |
POST | applications/{name}/rollbacks | discovery | Contributor on applications; rollbackapplication |
POST | applications/{name}/rollbacks/{rollbackId}/abort | discovery | Contributor on applications; rollbackapplication |
Trigger body: {"snapshotGeneration": <n>}. 409 while another
rollback of the application is pending or in progress; abort answers
409 unless the entry is pending.
Snapshots
| Method | Path | Service | Permission |
|---|---|---|---|
GET | snapshots | exporter | ReadOnly on applications; viewapplicationssnapshots. Volume usage and counts. |
GET | snapshots/{id}?scope=apps&namespace=<ns>&generation=<n> | exporter | ReadOnly on applications; viewapplicationssnapshots and viewapplicationsnapshotmanifest |
GET | snapshots/{id}/manifest?scope=apps&namespace=<ns>&generation=<n> | exporter | ReadOnly on applications; viewapplicationsnapshotmanifest. Accept: application/yaml for YAML, JSON otherwise. |
Secret data and stringData values are returned as [redacted].
Protection plans
| Method | Path | Service | Permission (on protection-plans) |
|---|---|---|---|
GET | protectionplans | exporter | ReadOnly; viewprotectionplans |
GET | protectionplans/{id} | exporter | ReadOnly; viewprotectionplans |
GET | policytemplates | discovery | ReadOnly; viewprotectionplans |
POST | protectionplans/prepare | discovery | Contributor; createprotectionplan |
POST | protectionplans/{id}/revise | discovery | Contributor; editprotectionplan |
POST | protectionplans/{id}/duplicate | discovery | Contributor; duplicateprotectionplan |
POST | protectionplans/{id}/cancel | discovery | Contributor; cancelprotectionplan |
POST | protectionplans/{id}/reactivate | discovery | Contributor; reactivateprotectionplan |
POST | protectionplans/{id}/decision | discovery | Owner; approveprotectionplan or rejectprotectionplan |
GET | protectionplans/{id}/status | discovery | ReadOnly; viewprotectionplans |
GET | protectionplans/{id}/violations?limit=<n>&result=<r> | discovery | ReadOnly; viewprotectionplanviolations |
DELETE | protectionplans/{id}/clear | discovery | Owner; deleteprotectionplan |
- Create and edit plans through discovery. The exporter's
POST protectionplansaccepts no lifecycle, approval or policy fields from a session, and itsPATCHandDELETEare Internal. decisionbody:{"decision": "approved" | "rejected", "comment": "…", "requestedAt": "<pending request>"}. A rejection needs a comment; a stalerequestedAtanswers409.enforceon anamespacesscope and a client-sentapprovalMode: automaticneed Owner.statuscomputes health on request and returnsplanId,phase,health, per-policypoliciesanddrift(missing,unexpected); it neither repairs nor stores.violations:limit50 by default, 200 at most;resultis one ofpass,fail,warn,error,skip.clearremoves the plan's policies, then the plan.
Reports
| Method | Path | Service | Permission (on protection-plans) |
|---|---|---|---|
POST | protectionplans/{id}/reports | discovery | Contributor; generateprotectionplanreport |
GET | protectionplans/{id}/reports | exporter | ReadOnly; viewprotectionplanreports |
GET | protectionplans/{id}/reports/download?report=<id>&format=<html|md|json|csv> | exporter | ReadOnly; downloadprotectionplanreport |
GET | reports?planId=<id>&trigger=<manual|cancel|end>&from=<RFC3339>&to=<RFC3339>&limit=<n> | exporter | ReadOnly; viewprotectionplanreports |
Generating answers 400 for a plan that never started and 429 with
Retry-After while two renders run. The cross-plan list defaults to 200
rows (1,000 at most); planId repeats or takes a comma list, and
X-Total-Count holds the match count before the limit.
Insights
| Method | Path | Service | Permission |
|---|---|---|---|
GET | insights | discovery | ReadOnly on insights |
GET | insights/applications?apps=<ns>/<name>,… | discovery | ReadOnly on insights. At most 100 applications. |
POST | insights/applications/{namespace}/{name}/analyze | analyzer | Contributor on insights; analyzeinsights |
POST | insights/applications/{namespace}/{name}/insights/{id}/triage | analyzer | Contributor on insights; triageinsights |
GET | insights/events?apps=<ns>/<name>,… | analyzer | ReadOnly on insights, or Owner on settings. Server-sent events. |
GET | insights/runtime | analyzer | ReadOnly on insights, or Owner on settings |
POST | insights/runtime/validate | analyzer | Owner on settings; controlainsights |
POST | insights/runtime/pull | analyzer | Owner on settings; controlainsights |
GET insights query parameters. category (incident,
recommendation); kind, severity, state (open, updated,
resolved, stale) and namespace, each a comma list; triage
(untriaged, acknowledged, dismissed, all); environment (a plan
environment id); q (text search); id and app
(<namespace>/<name>), comma lists; page (from 1); pageSize (1–100,
default 25); fresh=true to include every write acknowledged before the
request. Without state it returns open, updated and stale cards;
without triage it hides dismissed ones. The response holds items,
total, page, pageSize, counts and indexedAt, with an ETag
for If-None-Match. It answers 503 with Retry-After: 5 until the
index has loaded.
Triage body. {"action": "acknowledge" | "dismiss" | "reopen"}.
dismiss applies to recommendations only. 404 for an unknown card,
409 for an action the card cannot take in its state.
Analyzer limits. Manual analyze answers 429 when more than 100
jobs are queued. A user holds at most 8 event streams (429 beyond);
each stream re-checks the session every minute. In deep mode, analyze
answers 503 unless the runtime is ready. Pull answers 409 when
auto-pull is off and 400 for a model outside the licence catalog.
Users, groups and roles
| Method | Path | Service | Permission |
|---|---|---|---|
GET | users, users/{id} | exporter | ReadOnly on users. Administrators are visible only to Admin on ALL. |
POST | users | exporter | Contributor on users; createuser, plus the rights of any privileged field set |
PATCH | users/{id} | exporter | Authenticated: your own profile, or the rights of each privileged field changed (roles, groups, status) |
DELETE | auth/users/{id} | auth | Owner on users; deleteuser. Ends the user's sessions and removes references. |
GET | groups, groups/{id} | exporter | ReadOnly on groups |
POST | groups | exporter | Contributor on groups; creategroup |
PATCH | groups/{id} | exporter | Contributor on groups; editgroup, plus the member and role rules |
DELETE | auth/groups/{id} | auth | Owner on groups; deletegroup |
GET | accessroles, accessroles/{id} | exporter | ReadOnly on roles |
POST | accessroles | exporter | Contributor on roles; createrole |
PATCH | accessroles/{id} | exporter | Contributor on roles; editrole |
DELETE | auth/accessroles/{id} | auth | Owner on roles; deleterole |
The dashboard deletes through auth, which also removes every reference
to the record. The exporter serves DELETE users/{id}, groups/{id}
and accessroles/{id} with the same permissions.
Privileged fields: adding or removing roles needs Owner on users
(attachroletouser, removerolefromuser); groups need Owner on
groups (addusertogroup, removeuserfromgroup); account status needs
Admin on users (suspenduser). A role may not be granted above the
caller's own level, and nobody edits their own roles, groups or status.
Categories
| Method | Path | Service | Permission |
|---|---|---|---|
GET | categories?scope=<scope>, categories/{id} | exporter | Authenticated |
POST | categories | exporter | Authenticated; the category rules of its scope (add…category) |
PATCH | categories/{id} | exporter | Authenticated; edit…category of its scope |
DELETE | categories/{id} | exporter | Authenticated; delete…category of its scope |
Scopes: groups, roles, plan-environments, plan-tags.
Settings
| Method | Path | Service | Permission |
|---|---|---|---|
GET | config | exporter | ReadOnly on settings. The TelarkConfig, with the pinned Google key set merged in. |
PATCH | config | exporter | Per field: see below |
PATCH | auth/oidc/config | auth | Admin on ALL; editoidcconfig |
GET | cleanup/{type}, cleanup/{type}/{id} | exporter | ReadOnly on settings. Deletion-cleanup state. |
PUT, DELETE | cleanup/{type}/{id}/finalizer | exporter | Owner on settings |
config field | Permission |
|---|---|
excludedNamespaces, userSettings | Contributor on settings; editdiscoveryconfig |
snapshots | Contributor on settings; editsnapshotstorage |
ai | Owner on settings; controlainsights |
oidc | Admin on ALL; editoidcconfig |
cluster | Internal |
Sign-in and sessions
| Method | Path | Service | Permission |
|---|---|---|---|
GET | auth/config | auth | Public. Sign-in options. |
POST | auth/register/start | auth | Public |
POST | auth/passkeys | auth | Public for the registration register/start opened; a session to add a passkey to your account |
POST | auth/login/start | auth | Public |
POST | auth/login/finish | auth | Public. Returns the session token. |
POST | auth/oidc/google/nonce | auth | Public |
POST | auth/oidc/google/callback | auth | Public. Returns the session token; 503 when Google sign-in is not configured. |
POST | auth/logout | auth | Public. Deletes the session named by the token sent. |
GET | auth/permissions | auth | Authenticated. Your roles, each with its {scope, level, rules} entries. |
GET | auth/passkeys, auth/passkeys/{credentialId} | auth | Authenticated, your own |
PATCH, DELETE | auth/passkeys/{credentialId} | auth | Authenticated, your own |
POST | auth/passkeys/enroll-link | auth | Authenticated. A one-time link, valid 10 minutes, for your own account. |
GET | auth/sessions?user=<id>, auth/sessions/self | exporter | Authenticated, your own |
DELETE | auth/sessions/self, auth/sessions/{name} | exporter | Authenticated, your own. {name} is session-<sha256>; a raw token in the path is refused. |
Notifications
| Method | Path | Service | Permission |
|---|---|---|---|
GET | notifications?userId=<id>&limit=<n>&cursor=<c> | exporter | Authenticated, your own. limit 50 by default, 200 at most. |
POST | notifications/{id}/read?userId=<id> | exporter | Authenticated, your own |
POST | notifications/read?userId=<id> | exporter | Authenticated, your own. Marks all read. |
DELETE | notifications?userId=<id> | exporter | Authenticated, your own. Clears all. |
userId must be the caller's own id (403 otherwise). The list returns
items, unreadCount and nextCursor.
Health probes
GET status/live and GET status/ready are Public on every service
(auth also serves status/health). The analyzer's readiness depends on
Redis only, never on the model runtime.
Related
- CRD reference for the shape of every record
- Access control