Documentation menu
Getting started
New in v2.0
Feature deep dives
Reference
Endpoints
Endpoint reference
Every one of the 102 routes the control plane registers: verb, path, auth level, the fields each one accepts and a real response body.
Verified against the checkout built for v2.2.4 · updated 20 Oct 2026
The table on this page is not typed by hand. api/main.go is parsed at build time, including the routes registered through middleware, so the list is exactly what the binary under test registers — 102 routes across 4 groups. Each one carries what it accepts and what it answers.
68 need a token15 need an administrator19 are public probesGET 47POST 36PUT 8PATCH 3DELETE 8
How to read a route
| Row | What it tells you | Why it matters |
|---|---|---|
| GET verb chip | The HTTP verb, colour-coded consistently across this site. | A PATCH is a partial update; a PUT replaces the whole resource. |
/api/rules/{id} | The exact path, resolved through every mount prefix. | These paths are registered on a standard-library mux, so {id} matches one path segment. |
| Bearer / Admin / Public | The credential the route requires. | Public routes are probes and login exchanges. Admin routes are gated on the route and re-checked in the core. |
| Scope | What the query is filtered by server-side. | A tenant route can only ever read rows whose owner is the identity the token proves. |
| Statuses | The statuses this route can actually answer with. | Read the response reference for the body shape behind each code. |
Filter by verb
The verb chips under the search box are toggles: press POST and PUT to see only the routes that change something.
Filter by anything else
The search box matches the path, the handler name, the summary and every accepted field — searchidempotency and only the routes that take one remain.
No JavaScript?
Every card is rendered on the server. Filtering is an enhancement, so the full table is present and linkable with scripting disabled.
What each group is scoped to
Service health & system
12 routesThe unauthenticated surface an operator, a load balancer or the upgrade gate calls: liveness, readiness, the version block, the environment contract and the live probe of every service in the chain. These routes answer without a token because they must be callable precisely when authentication is the thing that is broken.
Scope · public probe
Authentication
7 routesPublic by definition — this is where a caller stops being anonymous. Three ways in: username and password, a single-use code the bot hands to an already-verified Telegram user, or signed Mini App init data. Every route here is inside the authentication rate class, so the brute-force budget is enforced before a token is ever minted.
Scope · public, rate-limited
Authenticated control plane
71 routesThe tenant surface. Each call resolves the caller from the verified token and then queries only that identity’s rows; an owner id in the body is never read. A row that belongs to somebody else is reported as missing, so ids cannot be probed.
Scope · tenant-scoped
Administration
12 routesInstallation-wide operations. The route is wrapped in the administrator gate, and the core re-checks the role on the other side of gRPC, so a forged or stale admin claim fails twice.
Scope · administrator only
All 102 routes
Grouped by the mux that owns them, in registration order, with the mount prefixes already applied. Statuses are the ones each handler can return; the shared envelope is described in the response reference.
Service health & system
12 routes · public probeThe unauthenticated surface an operator, a load balancer or the upgrade gate calls: liveness, readiness, the version block, the environment contract and the live probe of every service in the chain. These routes answer without a token because they must be callable precisely when authentication is the thing that is broken.
/api/health/services
Publich.ServicesHealthLive reachability of every service in the chain — core (gRPC channel plus pipeline loop), logger, web and this process — probed in parallel with short timeouts.
{
"status": "healthy",
"time": "2026-10-19T00:00:00Z",
"services": [
{ "name": "core", "online": true, "detail": "gRPC + pipeline loop", "latency_ms": 4 },
{ "name": "logger", "online": true, "detail": "log store answers", "latency_ms": 2 }
]
}/api/openapi.yaml
Publich.OpenAPIDocThe control plane’s own OpenAPI 3.1 document. It ships inside the image next to the code that serves it, so the published contract cannot drift from the binary.
Request and response bodies follow the shared envelope — see the response reference below.
/api/system/env
Publich.EnvContractHandlerThe environment contract: every recognised key with whether it is set and whether it is required, plus the hints that turn a missing key into an actionable next step. Values are never returned.
{
"checks": [
{ "key": "ATF_BOT_TOKEN", "set": true, "required": true, "hint": "Create the bot with @BotFather" }
],
"missing_required": [],
"missing_recommended": ["ATF_REDIS_PASSWORD"],
"deployment": "docker-compose",
"ok": true
}/api/system/setup
Publich.SetupReportOne answer to “is this deployment usable?”: the version block, the environment contract, a live probe of all four services, the rate-limiter summary and the next command to run.
{
"ready": true,
"ratelimit": { "mode": "redis", "enforcing": true },
"product_version": "2.2.4",
"api_version": "1.0.0",
"deployment": "docker-compose",
"checks": [{ "key": "ATF_BOT_TOKEN", "set": true, "required": true }],
"missing_required": [],
"missing_recommended": [],
"services": [{ "name": "core", "online": true, "latency_ms": 4, "detail": "gRPC + pipeline" }],
"next_steps": ["atf validate --runtime — full health re-check of the live stack"]
}/api/v1/health/services
Publich.ServicesHealthVersioned alias of /api/health/services.
Request and response bodies follow the shared envelope — see the response reference below.
/api/v1/system/env
Publich.EnvContractHandlerVersioned alias of /api/system/env.
Request and response bodies follow the shared envelope — see the response reference below.
/api/v1/system/setup
Publich.SetupReportVersioned alias of /api/system/setup — same body, same booleans-only rule.
Request and response bodies follow the shared envelope — see the response reference below.
/api/version
Publich.VersionThe client-negotiation block: product version, API contract version, the oldest client still supported, the commit that built the binary, and the capability keys a client may probe before using a feature.
{
"product_version": "2.2.4",
"api_version": "1.0.0",
"min_supported_client": "1.0.0",
"commit_sha": "07f3613",
"features": ["rules", "filters", "ai_configs", "sessions", "logs", "dlq", "backup", "system_setup", "env_contract"]
}/health
Publich.HealthAlias of /healthz, kept for gateways that were configured against it.
Request and response bodies follow the shared envelope — see the response reference below.
/healthz
Publich.HealthLiveness. Answers 200 as soon as the process can serve, with nothing checked downstream.
{
"status": "ok",
"time": "2026-10-19T00:00:00Z"
}/ready
Publich.ReadyAlias of /readyz.
Request and response bodies follow the shared envelope — see the response reference below.
/readyz
Publich.ReadyReadiness, and a strictly stronger signal than liveness: it pings the rate-limiter store and answers 503 when a wired limiter cannot enforce the budget it promised.
{
"status": "ready",
"ready": true,
"time": "2026-10-19T00:00:00Z",
"checks": [
{ "name": "ratelimit", "ready": true, "detail": "redis" }
]
}Authentication
7 routes · public, rate-limitedPublic by definition — this is where a caller stops being anonymous. Three ways in: username and password, a single-use code the bot hands to an already-verified Telegram user, or signed Mini App init data. Every route here is inside the authentication rate class, so the brute-force budget is enforced before a token is ever minted.
/api/auth/bot-login-link
Publich.AuthBotLoginLinkMints the caller’s own single-use dashboard login code and returns the relative link to open. Requires a valid Bearer token — the code is minted for the identity the token proves, never for an id in the request.
{
"code": "…",
"expires_at": 1790000000,
"link": "/dashboard/login?code=…"
}/api/auth/change-password
Publich.AuthChangePasswordChanges the caller’s own password; the old password is required and verified before the new one is hashed.
| Field | Type | Required | Meaning |
|---|---|---|---|
old_password | string | Yes | Verified before any change is stored. |
new_password | string | Yes | Rejected when weak. |
Request and response bodies follow the shared envelope — see the response reference below.
/api/auth/exchange-bot-token
Publich.AuthBotExchangeExchanges a single-use login code — minted by the bot for the Telegram user it already authenticated — for the same 7-day JWT.
| Field | Type | Required | Meaning |
|---|---|---|---|
login_code | string | Yes | Single-use, 10-minute code from the bot’s dashboard link. |
{
"success": true,
"token": "<jwt>",
"expires_at": 1790000000
}/api/auth/login
Publich.AuthLoginUsername and password → a 7-day HS256 JWT, its expiry and the account record.
| Field | Type | Required | Meaning |
|---|---|---|---|
username | string | Yes | Account username. |
password | string | Yes | Account password. |
telegram_user_id | int64 | Optional | Optional link proof when the call is issued from the bot. |
{
"success": true,
"token": "<jwt>",
"expires_at": 1790000000,
"account": { "user_id": 5094837833, "username": "operator", "is_admin": false }
}{
"username": "operator",
"password": "…"
}/api/auth/me
Publich.AuthMeThe identity behind the presented token: user id, username and whether it carries the administrator flag.
{
"user_id": 5094837833,
"username": "operator",
"is_admin": false
}/api/auth/register
Publich.AuthRegisterCreates a web account and returns the account record. The first account on a fresh install is the administrator.
| Field | Type | Required | Meaning |
|---|---|---|---|
username | string | Yes | Unique login name. |
password | string | Yes | Rejected when weak (WEAK_PASSWORD). |
telegram_user_id | int64 | Optional | Links the account to a Telegram identity at creation. |
Request and response bodies follow the shared envelope — see the response reference below.
/api/auth/tma
Publich.AuthTMAVerifies the HMAC-SHA256 signature of a Telegram Mini App initData payload against the bot token, then issues the same JWT for the verified numeric user id.
| Field | Type | Required | Meaning |
|---|---|---|---|
init_data | string | Yes | The raw window.Telegram.WebApp.initData string. |
Request and response bodies follow the shared envelope — see the response reference below.
Authenticated control plane
71 routes · tenant-scopedThe tenant surface. Each call resolves the caller from the verified token and then queries only that identity’s rows; an owner id in the body is never read. A row that belongs to somebody else is reported as missing, so ids cannot be probed.
/api/ai-configs
Bearerh.ListAIConfigsThe caller’s AI providers. The API key is write-only: it is returned masked or omitted, never in clear text.
Request and response bodies follow the shared envelope — see the response reference below.
/api/ai-configs
Bearerh.CreateAIConfigStores a provider configuration. The base URL is validated by the endpoint guard before it is accepted.
Request and response bodies follow the shared envelope — see the response reference below.
/api/ai-configs/{id}
Bearerh.UpdateAIConfigUpdates a provider configuration; sending a new key replaces the stored one.
Request and response bodies follow the shared envelope — see the response reference below.
/api/ai-configs/{id}
Bearerh.DeleteAIConfigDeletes a provider configuration and its stored key.
Request and response bodies follow the shared envelope — see the response reference below.
/api/ai-configs/check-key
Bearerh.CheckProviderKeyHealth-probes a provider with the key that was typed, before it is stored, and reports whether the model actually answered.
Request and response bodies follow the shared envelope — see the response reference below.
/api/ai-configs/providers
Bearerh.ListAIProvidersThe provider catalogue: known endpoints, default models and which fields each one needs.
Request and response bodies follow the shared envelope — see the response reference below.
/api/audit/events
Bearerh.QueryAuditEventsTenant-scoped audit events: who changed what, when, and under which correlation id.
Request and response bodies follow the shared envelope — see the response reference below.
/api/backup/export
Bearerh.BackupExportStarts a whole-installation export as a durable async task (kind backup.export).
Request and response bodies follow the shared envelope — see the response reference below.
/api/backup/import
Bearerh.BackupImportImports a backup bundle into the caller’s tenant; encrypted bundles are decrypted with the operator key.
Request and response bodies follow the shared envelope — see the response reference below.
/api/bot-tokens
Bearerh.ListBotTokensThe bots this tenant has registered, each with the tasks that inherit from it.
Request and response bodies follow the shared envelope — see the response reference below.
/api/bot-tokens
Bearerh.CreateBotTokenRegisters a bot token. The token is validated with Telegram before it is stored.
Request and response bodies follow the shared envelope — see the response reference below.
/api/bot-tokens/{id}
Bearerh.DeleteBotTokenRemoves a bot registration; tasks attached to it must be re-pointed.
Request and response bodies follow the shared envelope — see the response reference below.
/api/bot-tokens/{id}/defaults
Bearerh.GetBotDefaultsThe defaults every task attached to this bot inherits, with where each value comes from.
Request and response bodies follow the shared envelope — see the response reference below.
/api/bot-tokens/{id}/defaults
Bearerh.SetBotDefaultsSets the inherited defaults for every task attached to this bot.
Request and response bodies follow the shared envelope — see the response reference below.
/api/client/credentials
Bearerh.ClientSaveCredentialsStores the caller’s personal client credentials. Write-only: they are never read back.
Request and response bodies follow the shared envelope — see the response reference below.
/api/client/settings
Bearerh.ClientGetSettingsThe caller’s client-side preferences (theme, language, notification choices).
Request and response bodies follow the shared envelope — see the response reference below.
/api/diagnostics
Bearerh.DiagnosticsPreflight findings for the caller’s own rules, sessions and AI configs — the problems that would make a task fail, reported before it runs.
Request and response bodies follow the shared envelope — see the response reference below.
/api/dlq
Bearerh.ListDeadLetterThe caller’s dead-letter entries with their failure reason and original target.
Request and response bodies follow the shared envelope — see the response reference below.
/api/dlq
Bearerh.PurgeDeadLetterPurges the caller’s dead-letter queue. Ownership is applied before the delete, not after.
Request and response bodies follow the shared envelope — see the response reference below.
/api/dlq/{id}/retry
Bearerh.ReplayDeadLetterReplays one dead-lettered delivery. A refused replay still returns its reason on the wire instead of an empty body.
Request and response bodies follow the shared envelope — see the response reference below.
/api/filters
Bearerh.ListFiltersLists the caller’s saved keyword filters (blacklist, whitelist, link and media gates).
Request and response bodies follow the shared envelope — see the response reference below.
/api/filters
Bearerh.CreateFilterCreates a reusable filter that tasks can reference instead of repeating keyword lists.
Request and response bodies follow the shared envelope — see the response reference below.
/api/filters/{id}
Bearerh.UpdateFilterReplaces a filter definition.
Request and response bodies follow the shared envelope — see the response reference below.
/api/filters/{id}
Bearerh.DeleteFilterDeletes a filter; tasks that referenced it keep their own inline rules.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs
Bearerh.QueryLogsBounded, filterable query over the caller’s log history (level, task, time window, limit).
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/diagnostics/start
Adminh.RequireAdmin(http.HandlerFunc(h.LogDiagnosticsStart))Starts a bounded diagnostic capture for support. Administrator-only.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/diagnostics/stop
Adminh.RequireAdmin(http.HandlerFunc(h.LogDiagnosticsStop))Stops the diagnostic capture and returns what it collected. Administrator-only.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/export
Bearerh.ExportLogsA downloadable copy of the filtered history as JSON or CSV, so evidence can leave the box without screen-scraping.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/health
Bearerh.LoggingHealthWhether the logger answers, and whether the policy in force matches the one configured.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/policy
Bearerh.LogPolicyThe collection policy this process is actually applying: levels, retention and sampling.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/policy
Adminh.RequireAdmin(http.HandlerFunc(h.LogPolicyUpdate))Changes what the core collects, through the process that enforces it. Administrator-only and audited, because this is the one control that decides what the evidence trail keeps.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/purge
Bearerh.PurgeLogsDeletes the caller’s stored log history inside the requested window. A tenant must name one of their own tasks: the archive is one shared store with no tenant column on this path, so the installation-wide purge is administrator-only and answers 403 otherwise.
Request and response bodies follow the shared envelope — see the response reference below.
/api/logs/stats
Bearerh.LogStatsCounts per level and per task over a window — the numbers behind the log explorer.
Request and response bodies follow the shared envelope — see the response reference below.
/api/prompts
Bearerh.ListPromptTemplatesThe caller’s AI rewrite prompt templates.
Request and response bodies follow the shared envelope — see the response reference below.
/api/prompts
Bearerh.CreatePromptTemplateCreates a prompt template; new versions are stored rather than overwriting history.
Request and response bodies follow the shared envelope — see the response reference below.
/api/prompts/{id}
Bearerh.UpdatePromptTemplateReplaces a prompt template’s body and name.
Request and response bodies follow the shared envelope — see the response reference below.
/api/prompts/{id}
Bearerh.DeletePromptTemplateDeletes a prompt template. Tasks that referenced it fall back to the default prompt.
Request and response bodies follow the shared envelope — see the response reference below.
/api/prompts/test
Bearerh.TestPromptRuns a prompt against sample text through the tenant’s AI provider and returns the model output.
Request and response bodies follow the shared envelope — see the response reference below.
/api/pv-responder
Bearerh.GetPVResponderThe private-chat auto-responder configuration: persona, typing delay, cooldown, history depth.
Request and response bodies follow the shared envelope — see the response reference below.
/api/pv-responder
Bearerh.SetPVResponderCreates or replaces the auto-responder configuration.
Request and response bodies follow the shared envelope — see the response reference below.
/api/pv-responder
Bearerh.SetPVResponderSame write path as POST, kept for clients that PUT.
Request and response bodies follow the shared envelope — see the response reference below.
/api/queue
Bearerh.DeliveryStatsQueue depth and worker state. A healthy queue reports zeroes; it never reports a backlog it does not have.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules
Bearerh.ListRulesLists the caller’s forwarding tasks, newest first, including their lists of sources and targets.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules
Bearerh.CreateRuleCreates a forwarding task. The first source and the first target are mirrored into the legacy scalar columns by one write path.
| Field | Type | Required | Meaning |
|---|---|---|---|
name | string | Yes | Human label shown in every client. |
source_chat_ids | string[] | Optional | M sources; the first entry becomes the primary source. |
target_chat_ids | string[] | Optional | N targets; the first entry becomes the primary target. |
mode | string | Optional | copy or forward — the delivery mode applied to every target. |
settings | object | Optional | Per-task cleaner, filters, header/footer, AI and schedule settings. |
{
"name": "Desk feed → VIP + free tier",
"source_chat_ids": ["@desk_feed", "-1001695513745"],
"target_chat_ids": ["-1002000000001", "-1002000000002"],
"mode": "copy",
"settings": { "clean_links": true, "header_template": "📰 [[ORIGIN_NAME]]" }
}/api/rules/{id}
Bearerh.GetRuleOne task, ownership-checked before the read.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}
Bearerh.UpdateRuleFull update of a task. A stale version is refused rather than silently overwriting a concurrent edit.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}
Bearerh.UpdateRulePartial update: the body carries only what changes and update_mask names it — the only way to set a value to false, zero or empty.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}
Bearerh.DeleteRuleDeletes a task and its policy. The delivery history stays queryable by the caller.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/duplicate
Bearerh.DuplicateRuleClones a task — same policy, same lists — as a new row owned by the caller.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/logs
Bearerh.RuleLogsOne task’s complete delivery history, ownership-checked before the read.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/pause
Bearerh.PauseRulePauses delivery for one task; in-flight jobs are deferred rather than failed.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/restart
Bearerh.RestartRuleRestarts the poller after a stop, re-reading the task’s current settings.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/resume
Bearerh.ResumeRuleResumes a paused task and drains what was deferred.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/route-path
Bearerh.RoutePathQuickSetSets the source→target path in one call, keeping the legacy mirror consistent.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/settings
Bearerh.GetRuleSettingsStored settings, the schema that describes them, and the effective values with the provenance of each one.
{
"success": true,
"settings": { "clean_links": true },
"schema": { "type": "object" },
"effective": { "clean_links": { "value": true, "source": "rule" } }
}/api/rules/{id}/settings
Bearerh.UpdateRuleSettingsReplaces the task’s stored settings after schema validation.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/settings
Bearerh.UpdateRuleSettingsApplies only the named settings; everything else keeps its current value.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/stop
Bearerh.StopRuleStops the task’s poller. Unlike pause, nothing is queued for later.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/{id}/toggle
Bearerh.ToggleRuleFlips enabled state without touching any other field.
Request and response bodies follow the shared envelope — see the response reference below.
/api/rules/settings/schema
Bearerh.GetRuleSettingsSchemaThe JSON schema of the per-task settings surface. It needs no task, so an editor can be built before the user owns anything.
Request and response bodies follow the shared envelope — see the response reference below.
/api/sessions
Bearerh.ListSessionsLists the caller’s Telegram sessions with their account, status and last-seen time.
Request and response bodies follow the shared envelope — see the response reference below.
/api/sessions/{id}
Bearerh.TerminateSessionTerminates a session and drops its live client. The stored session file is removed.
Request and response bodies follow the shared envelope — see the response reference below.
/api/sessions/{id}/backup
Bearerh.BackupSessionStarts a session backup as a durable async task (kind session.backup) and returns the task row.
Request and response bodies follow the shared envelope — see the response reference below.
/api/sessions/{sessionId}/chats
Bearerh.ListChatsThe chat list for the source and target pickers, scoped entirely from the token identity.
Request and response bodies follow the shared envelope — see the response reference below.
/api/simulate
Bearerh.TestRuleDry-runs a task against a sample message and returns the text that would be delivered — the cleaner, filters, replacements, header and footer applied in the real order.
| Field | Type | Required | Meaning |
|---|---|---|---|
rule_id | string | Yes | The task whose policy is applied. |
text | string | Yes | Sample message body. |
Request and response bodies follow the shared envelope — see the response reference below.
/api/stats
Bearerh.GetStatsAggregate counters for the caller’s tasks: delivered, failed, queued and dead-lettered.
Request and response bodies follow the shared envelope — see the response reference below.
/api/tasks
Bearerh.ListTasksLists the caller’s durable async jobs, filterable by status and kind, with a bounded page (limit 1–200, default 50).
| Field | Type | Required | Meaning |
|---|---|---|---|
status | string | Optional | PENDING · RUNNING · RETRY_WAIT · SUCCEEDED · FAILED · CANCELLED |
kind | string | Optional | session.backup · dlq.replay · dlq.purge · backup.export |
limit | int | Optional | 1–200, default 50. |
offset | int | Optional | Default 0. |
{
"tasks": [
{
"id": "6f1c…",
"owner_user_id": 5094837833,
"kind": "dlq.replay",
"status": "RUNNING",
"attempt": 1,
"max_attempts": 3,
"created_at": 1790000000
}
],
"total": 1,
"limit": 50,
"offset": 0
}/api/tasks
Bearerh.CreateTaskRegisters a durable, tenant-owned job. Resubmitting the same (owner, kind, idempotency_key) returns the original task with already_existed:true instead of a duplicate.
| Field | Type | Required | Meaning |
|---|---|---|---|
kind | string | Yes | One of session.backup, dlq.replay, dlq.purge, backup.export. |
payload | object | Optional | JSON object; ≤ 64 KiB; stored canonically. |
idempotency_key | string | Optional | Client-chosen; makes retries safe. |
max_attempts | int | Optional | Default 3, clamped to 8. |
{
"task": {
"id": "6f1c…",
"owner_user_id": 5094837833,
"kind": "dlq.replay",
"status": "PENDING",
"idempotency_key": "replay-2026-10-19",
"attempt": 0,
"max_attempts": 3
},
"already_existed": false,
"id": "6f1c…",
"status": "PENDING"
}{
"kind": "dlq.replay",
"payload": { "ids": ["a1"] },
"idempotency_key": "replay-2026-10-19",
"max_attempts": 3
}/api/tasks/{id}
Bearerh.GetTaskOne job. A job that belongs to another tenant is reported as missing, exactly like a job that does not exist.
Request and response bodies follow the shared envelope — see the response reference below.
/api/tasks/{id}/cancel
Bearerh.CancelTaskRequests cancellation. A terminal job refuses with not_cancellable; a running one with running_not_cancellable.
Request and response bodies follow the shared envelope — see the response reference below.
/api/tasks/{id}/retry
Bearerh.RetryTaskRe-queues a FAILED job with a fresh attempt budget. Any other state refuses with not_retryable.
Request and response bodies follow the shared envelope — see the response reference below.
Administration
12 routes · administrator onlyInstallation-wide operations. The route is wrapped in the administrator gate, and the core re-checks the role on the other side of gRPC, so a forged or stale admin claim fails twice.
/api/admin/admins
Adminh.AdminListAdminsThe administrator roster.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/admins
Adminh.AdminAddAdminGrants the administrator flag to an existing account.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/admins/{id}
Adminh.AdminRemoveAdminRevokes the administrator flag. The last remaining administrator cannot be removed.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/broadcast
Adminh.AdminBroadcastSends an operator announcement to every linked user through the bot.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/extensions
Adminh.AdminListExtensionsInstalled extensions and whether each one is enabled.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/extensions/{id}/toggle
Adminh.AdminToggleExtensionEnables or disables one extension.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/overview
Adminh.AdminOverviewInstallation totals: accounts, tasks, deliveries, queue depth and service health in one response.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/ratelimit
Adminh.RateLimitStatusThe limiter’s own control surface: effective class policies, whether the store is reachable, and whether requests are currently served by the in-process fallback.
{
"enabled": true,
"backend": "redis",
"degraded": false,
"classes": {
"auth": { "limit": 30, "window_seconds": 60, "burst": 10, "scope": "ip", "fail": "closed" },
"read": { "limit": 600, "window_seconds": 60, "burst": 120, "scope": "u", "fail": "local" },
"write": { "limit": 120, "window_seconds": 60, "burst": 30, "scope": "u", "fail": "local" },
"admin": { "limit": 300, "window_seconds": 60, "burst": 60, "scope": "u", "fail": "local" }
}
}/api/admin/settings
Adminh.AdminGetSettingsInstallation settings currently in force.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/settings
Adminh.AdminSaveSettingsSaves installation settings; secret values are write-only and never echoed.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/users
Adminh.AdminListUsersPaginated account list with status and link state.
Request and response bodies follow the shared envelope — see the response reference below.
/api/admin/users/{id}/status
Adminh.AdminSetUserStatusEnables or disables one account. A disabled account’s tokens stop resolving on the next request.
Request and response bodies follow the shared envelope — see the response reference below.
No route matches that filter. Clear the search box or release a verb chip to see the full 102-route table.
Versioning and aliases
- Two contract versions are exposed on purpose. The product version (
2.2.4) moves with releases; the API contract version stays at1.0.0until a breaking change lands. - Probes answer on both shapes. Health and system routes exist under
/api/…and/api/v1/…; the versioned form is what the mobile client pins. - Clients negotiate before they call. Read
/api/versionand checkmin_supported_clientplus thefeatureskeys instead of probing endpoints for their presence. - The shipped schema is authoritative. The API serves its own OpenAPI document at
/api/openapi.yaml, baked into the image next to the code that serves it.