Reference

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

TopicRule
AuthenticationX-Session-Token: <token> on every route except the Public ones. No cookie, no query parameter.
PermissionLevel on scope plus the action whose deny rule <scope>.<action>.deny withholds it. A deny rule wins over any level. See Access control.
AuthenticatedA valid session is enough; the handler limits the call to the caller's own data.
InternalService token only (X-Service-Token). Not reachable through the dashboard proxy, which answers 404 for internal/ paths. Omitted below.
Unmapped route403.
IdentityTaken from the session. X-User-ID, X-Username and X-Email sent by a client are stripped.
Body keysUser, group, role, category and protection-plan writes refuse a key that is not exactly a field name of the record (400).
Body size413 above 1 MiB (exporter, plan and rollback routes) or 64 KiB (analyzer).
Outage503 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

MethodPathServicePermission
GETapplicationsexporterReadOnly on applications
GETapplications/{name}exporterReadOnly on applications
PATCHapplications/{name}exporterContributor on applications; editapplication. Display name and description only.
POSTapplications/{name}/syncdiscoveryContributor on applications; forceapplicationsync
POSTapplications/{name}/resetdiscoveryOwner on applications; deleteapplication
GETdiscovery/statusdiscoveryReadOnly on applications
GETcluster/namespacesdiscoveryAuthenticated; the handler requires ReadOnly on applications or on insights
GETcluster/namespaces/{namespace}/workloadsdiscoveryReadOnly on applications
GETcluster/namespaces/{namespace}/resourcesdiscoveryReadOnly 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

MethodPathServicePermission
GETapplications/{name}/rollbacksexporterReadOnly on applications; viewapplicationsrollbacks
GETapplications/{name}/rollbacks/{rollbackId}exporterReadOnly on applications; viewapplicationsrollbacks
POSTapplications/{name}/rollbacksdiscoveryContributor on applications; rollbackapplication
POSTapplications/{name}/rollbacks/{rollbackId}/abortdiscoveryContributor 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

MethodPathServicePermission
GETsnapshotsexporterReadOnly on applications; viewapplicationssnapshots. Volume usage and counts.
GETsnapshots/{id}?scope=apps&namespace=<ns>&generation=<n>exporterReadOnly on applications; viewapplicationssnapshots and viewapplicationsnapshotmanifest
GETsnapshots/{id}/manifest?scope=apps&namespace=<ns>&generation=<n>exporterReadOnly on applications; viewapplicationsnapshotmanifest. Accept: application/yaml for YAML, JSON otherwise.

Secret data and stringData values are returned as [redacted].

Protection plans

MethodPathServicePermission (on protection-plans)
GETprotectionplansexporterReadOnly; viewprotectionplans
GETprotectionplans/{id}exporterReadOnly; viewprotectionplans
GETpolicytemplatesdiscoveryReadOnly; viewprotectionplans
POSTprotectionplans/preparediscoveryContributor; createprotectionplan
POSTprotectionplans/{id}/revisediscoveryContributor; editprotectionplan
POSTprotectionplans/{id}/duplicatediscoveryContributor; duplicateprotectionplan
POSTprotectionplans/{id}/canceldiscoveryContributor; cancelprotectionplan
POSTprotectionplans/{id}/reactivatediscoveryContributor; reactivateprotectionplan
POSTprotectionplans/{id}/decisiondiscoveryOwner; approveprotectionplan or rejectprotectionplan
GETprotectionplans/{id}/statusdiscoveryReadOnly; viewprotectionplans
GETprotectionplans/{id}/violations?limit=<n>&result=<r>discoveryReadOnly; viewprotectionplanviolations
DELETEprotectionplans/{id}/cleardiscoveryOwner; deleteprotectionplan
  • Create and edit plans through discovery. The exporter's POST protectionplans accepts no lifecycle, approval or policy fields from a session, and its PATCH and DELETE are Internal.
  • decision body: {"decision": "approved" | "rejected", "comment": "…", "requestedAt": "<pending request>"}. A rejection needs a comment; a stale requestedAt answers 409.
  • enforce on a namespaces scope and a client-sent approvalMode: automatic need Owner.
  • status computes health on request and returns planId, phase, health, per-policy policies and drift (missing, unexpected); it neither repairs nor stores.
  • violations: limit 50 by default, 200 at most; result is one of pass, fail, warn, error, skip.
  • clear removes the plan's policies, then the plan.

Reports

MethodPathServicePermission (on protection-plans)
POSTprotectionplans/{id}/reportsdiscoveryContributor; generateprotectionplanreport
GETprotectionplans/{id}/reportsexporterReadOnly; viewprotectionplanreports
GETprotectionplans/{id}/reports/download?report=<id>&format=<html|md|json|csv>exporterReadOnly; downloadprotectionplanreport
GETreports?planId=<id>&trigger=<manual|cancel|end>&from=<RFC3339>&to=<RFC3339>&limit=<n>exporterReadOnly; 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

MethodPathServicePermission
GETinsightsdiscoveryReadOnly on insights
GETinsights/applications?apps=<ns>/<name>,…discoveryReadOnly on insights. At most 100 applications.
POSTinsights/applications/{namespace}/{name}/analyzeanalyzerContributor on insights; analyzeinsights
POSTinsights/applications/{namespace}/{name}/insights/{id}/triageanalyzerContributor on insights; triageinsights
GETinsights/events?apps=<ns>/<name>,…analyzerReadOnly on insights, or Owner on settings. Server-sent events.
GETinsights/runtimeanalyzerReadOnly on insights, or Owner on settings
POSTinsights/runtime/validateanalyzerOwner on settings; controlainsights
POSTinsights/runtime/pullanalyzerOwner 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

MethodPathServicePermission
GETusers, users/{id}exporterReadOnly on users. Administrators are visible only to Admin on ALL.
POSTusersexporterContributor on users; createuser, plus the rights of any privileged field set
PATCHusers/{id}exporterAuthenticated: your own profile, or the rights of each privileged field changed (roles, groups, status)
DELETEauth/users/{id}authOwner on users; deleteuser. Ends the user's sessions and removes references.
GETgroups, groups/{id}exporterReadOnly on groups
POSTgroupsexporterContributor on groups; creategroup
PATCHgroups/{id}exporterContributor on groups; editgroup, plus the member and role rules
DELETEauth/groups/{id}authOwner on groups; deletegroup
GETaccessroles, accessroles/{id}exporterReadOnly on roles
POSTaccessrolesexporterContributor on roles; createrole
PATCHaccessroles/{id}exporterContributor on roles; editrole
DELETEauth/accessroles/{id}authOwner 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

MethodPathServicePermission
GETcategories?scope=<scope>, categories/{id}exporterAuthenticated
POSTcategoriesexporterAuthenticated; the category rules of its scope (add…category)
PATCHcategories/{id}exporterAuthenticated; edit…category of its scope
DELETEcategories/{id}exporterAuthenticated; delete…category of its scope

Scopes: groups, roles, plan-environments, plan-tags.

Settings

MethodPathServicePermission
GETconfigexporterReadOnly on settings. The TelarkConfig, with the pinned Google key set merged in.
PATCHconfigexporterPer field: see below
PATCHauth/oidc/configauthAdmin on ALL; editoidcconfig
GETcleanup/{type}, cleanup/{type}/{id}exporterReadOnly on settings. Deletion-cleanup state.
PUT, DELETEcleanup/{type}/{id}/finalizerexporterOwner on settings
config fieldPermission
excludedNamespaces, userSettingsContributor on settings; editdiscoveryconfig
snapshotsContributor on settings; editsnapshotstorage
aiOwner on settings; controlainsights
oidcAdmin on ALL; editoidcconfig
clusterInternal

Sign-in and sessions

MethodPathServicePermission
GETauth/configauthPublic. Sign-in options.
POSTauth/register/startauthPublic
POSTauth/passkeysauthPublic for the registration register/start opened; a session to add a passkey to your account
POSTauth/login/startauthPublic
POSTauth/login/finishauthPublic. Returns the session token.
POSTauth/oidc/google/nonceauthPublic
POSTauth/oidc/google/callbackauthPublic. Returns the session token; 503 when Google sign-in is not configured.
POSTauth/logoutauthPublic. Deletes the session named by the token sent.
GETauth/permissionsauthAuthenticated. Your roles, each with its {scope, level, rules} entries.
GETauth/passkeys, auth/passkeys/{credentialId}authAuthenticated, your own
PATCH, DELETEauth/passkeys/{credentialId}authAuthenticated, your own
POSTauth/passkeys/enroll-linkauthAuthenticated. A one-time link, valid 10 minutes, for your own account.
GETauth/sessions?user=<id>, auth/sessions/selfexporterAuthenticated, your own
DELETEauth/sessions/self, auth/sessions/{name}exporterAuthenticated, your own. {name} is session-<sha256>; a raw token in the path is refused.

Notifications

MethodPathServicePermission
GETnotifications?userId=<id>&limit=<n>&cursor=<c>exporterAuthenticated, your own. limit 50 by default, 200 at most.
POSTnotifications/{id}/read?userId=<id>exporterAuthenticated, your own
POSTnotifications/read?userId=<id>exporterAuthenticated, your own. Marks all read.
DELETEnotifications?userId=<id>exporterAuthenticated, 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.