REST API

The Developer API is rooted at /v1 on the control plane origin. Every route authenticates an Environment-bound API key with Authorization: Bearer <key>; see Authentication. The TypeScript HelmrClient wraps these routes.

Human-session permission management uses the /api Roles, Groups, Role Grants and member-permissions routes. These routes are shared by the Console and CLI and do not accept workload API keys.

Routes

Method Path
DELETE /v1/computers/{computerID}
GET /v1/agents
GET /v1/agents/{agent}
GET /v1/commands/{commandID}
GET /v1/commands/{commandID}/logs
GET /v1/computers
GET /v1/computers/{computerID}
GET /v1/computers/{computerID}/sessions
GET /v1/computers/{computerID}/commands
GET /v1/deployments
GET /v1/deployments/current
GET /v1/deployments/{deploymentID}
GET /v1/deployments/{deploymentID}/events
GET /v1/triggers
GET /v1/triggers/{triggerID}
GET /v1/triggers/{triggerID}/occurrences
GET /v1/secrets
GET /v1/secrets/{secret}
GET /v1/sessions
GET /v1/sessions/{sessionID}
GET /v1/sessions/{sessionID}/events
GET /v1/sessions/{sessionID}/turns
GET /v1/sessions/{sessionID}/turns/{turnID}
GET /v1/sessions/{sessionID}/turns/{turnID}/asks
GET /v1/sessions/{sessionID}/turns/{turnID}/asks/{askID}
GET /v1/templates
GET /v1/templates/{template}
POST /v1/commands/{commandID}/cancel
POST /v1/computers
POST /v1/computers/{computerID}/exec
POST /v1/deployment-bundles/finalize
POST /v1/deployment-bundles/upload-plan
PUT /v1/deployment-bundles/{bundleDigest}/objects/{objectDigest}
POST /v1/deployments/{deploymentID}/promote
POST /v1/secrets
POST /v1/secrets/{secret}/revoke
POST /v1/secrets/{secret}/rotate
POST /v1/sessions
POST /v1/sessions/{sessionID}/cancel
POST /v1/sessions/{sessionID}/close
POST /v1/sessions/{sessionID}/enqueue
POST /v1/sessions/{sessionID}/interrupt
POST /v1/sessions/{sessionID}/resume
POST /v1/sessions/{sessionID}/turns/{turnID}/asks/{askID}/answer
POST /v1/sessions/{sessionID}/turns/{turnID}/interrupt
POST /v1/sessions/{sessionID}/turns/{turnID}/messages

{agent} and {template} are identifiers declared in code. {secret} is the Environment-scoped ID chosen when creating the Secret, such as GITHUB_TOKEN. Project and Environment selectors use the readable project and environment IDs shown in the Console. Instance resource IDs are server-assigned UUIDs. Agent/Template list and get resolve the current Deployment unless deployment_id selects an exact Deployment. Responses include that resolved deployment_id; list envelopes are agents and templates.

Resource Identifier and inspection fields
Agent agent, default template, deployment_id
Template template, resources, deployment_id
Session agent, template (the pinned Agent default), deployment_id, optional computer_id
Computer template, deployment_id (its actual creation origin), optional instance key
Trigger agent, deployment_id

Template resources use milliCpu, memoryMiB and optional diskMiB. The local agent({ id }) / template({ id }) declaration value is called agent / template in this API. It is never guessed to be a UUID, even if it looks like one. Session creation uses {"agent":"support"}; Computer creation uses {"template":"browser"}. Both use current for new work.

A missing current Deployment returns no_current_deployment. An unknown selected Deployment returns deployment_not_found. A missing Agent/Template in a resolved, authorized Deployment returns not_found with error.details.deployment_id; it does not fall back to another Deployment or claim the stable identity was deleted.

Session and Trigger lists accept the declared agent identifier. agent resolves stable identity independently of current membership, so retained history remains searchable after an Agent is removed from current or deleted; Trigger history requires view=all.

Computer /sessions and /commands return current usage, including work whose process cleanup is pending. They are not history endpoints. Entries contain id, usage_state and created_at; usage state does not replace resource lifecycle status. The page envelopes are sessions or commands, with next_cursor when needed. Each collection has its own cursor.

GET /v1/computers?secret=NAME lists non-deleted Computers that received a raw value of that Secret. Each item then carries secret_exposure: received when a process or Command on the Computer received the value directly, or image when its image was prepared with the value, so the Computer may hold it. The filter pages with cursor and limit and cannot be combined with key.

Secret creation only makes new names. Creating an existing active name returns 409 conflict; a revoked name returns 409 secret_revoked. Rotate a revoked Secret to reactivate it with its existing bindings. idempotency_key is optional for create, rotate and revoke.

Conventions

  • Request and response bodies are JSON. Most fields use snake case. Secret bindings use secret, env, file and allowedOrigins, the same names as the SDK.
  • Inputs are JSON values validated by the Agent’s input schema. Agents without an input schema accept arrays of text parts, as do Turn messages. Session creation and enqueue carry input; a Turn message carries message, as in {"message":[{"type":"text","text":"Continue"}]}. Output and responses are Content arrays. See Agent.
  • Retention fields are read-only milliseconds from the definition: a Session’s close_after_idle_ms comes from its pinned Agent definition and a Computer’s delete_after_unused_ms from its origin Template. null means never. Requests cannot override them.
  • Mutations accept an idempotency_key; question answers use answer_id. Reuse the same value and body to retry an uncertain request. See Errors.
  • Session creation returns a Session and an optional initial Turn admission; exec returns a Command admission. Neither confirms completion.
  • Collections use opaque cursors; Session events use integer sequences. See Pagination.
  • Command logs contain base64-encoded byte chunks or explicit gaps, with reconnect cursors and an output_state.
  • Session events contain authored content and lifecycle facts. Process stdout and stderr are not exposed. See Session events.

Other route families

Prefix Purpose
/api Management used by the console and by CLI commands with a saved login.
/admin/api/v1 Deployment administration, including operator authentication, credentials and recovery.
/capacity/v1 Capacity scaling for self-hosted deployments. See Capacity.
/worker/v1 Worker control.
/integrations/slack/apps/{registrationID}/events, /interactions Slack app callbacks.
/healthz, /readyz Liveness and readiness.

These families have their own authentication and are not alternatives to the Developer API.

Management and administration boundaries

The ordinary Console signs in at /login; deployment operators sign in at /admin/login. /setup coordinates the first self-hosted organization with both an operator session and the ordinary account that will own it. Organization owners are not deployment operators.

Within /api, /auth/* handles ordinary authentication and CLI consent, /me returns the account projection, and /account/* manages that account. /organizations lists the account’s memberships; /organization reads the explicitly selected organization. Organization resources such as /members retain the X-Helmr-Organization selection contract. An account login alone does not grant access to any organization.

/admin/api/v1 also includes /me, /setup, /auth/*, /credentials/*, /enrollment/* and /account-repairs/*. These are browser-cookie or browser-bound ceremony APIs, not an additional CLI or bearer-token login method. The v1 administration prefix does not make their credentials interchangeable with Developer, Worker or Capacity API credentials. See operator authentication for the per-operation requirements.

Authentication steps use options, verify and complete to distinguish challenge preparation, proof verification and registration.

Trigger activations and occurrences

GET /v1/triggers accepts agent, logical trigger key, view, limit and cursor. view=current is the default; view=all includes retained historical activations. Keep the view and filters unchanged when using a cursor. A Trigger ID identifies one activation, not the logical key shared across promotions.

GET /v1/triggers/{triggerID}/occurrences requires Session read access to the Agent. It accepts limit (1–100, default 50) and cursor, and returns an occurrences array with optional next_cursor. Each outcome has scheduled_at, evaluated_at, disposition (admitted, missed or rejected), and nullable reason, session_id and turn_id. A cursor belongs to that Environment and activation; it cannot be reused for another activation.

Human-session equivalents are available under /api/projects/{project}/environments/{environment}/triggers. Agent Delete and retained status use separate human management routes; see Agent lifecycle.

Deployment uploads

Upload planning returns the bundle digest and missing object descriptors (digest, size_bytes, media_type). Send each object’s bytes to the authenticated PUT route on the same Helmr origin, with the descriptor’s exact Content-Length and Content-Type, then finalize the bundle. Each PUT checks current Environment publish permission and membership in an admitted bundle. A 204 acknowledges quarantine storage; finalization separately verifies and publishes the deployment. No direct object-store URL or redirect is part of this protocol.

Objects and their total bundle remain limited to 4 GiB, with at most 513 objects. Per-process and per-organization upload capacity, inactivity and maximum transfer duration are explicit operator settings. They apply equally to Managed Cloud and self-hosted installations. The CLI waits on 429 according to Retry-After, within its configurable per-object deadline, and reconciles a lost success response through upload planning. Other interrupted uploads can be rerun with the same bundle. Client and ingress limits can end a transfer before its server deadline; configure and qualify the complete path. Quarantined inputs expire under the AWS recipe’s one-day lifecycle (and noncurrent versions after one day); S3 applies expiration asynchronously. Rerun upload planning if an unfinalized input has expired.

Deployment promotion

POST /v1/deployments/{deploymentID}/promote returns 202 with preparation_state: "preparing" while Environment preparation runs; repeat the request after preparation finishes. A completed promotion returns 200 with the Deployment and, when non-empty:

Field Meaning
restored_agents Keys of deleted Agents the Deployment declares; promotion restored them.
waiting_triggers { "agent", "trigger" } entries whose Slack destination waits for a connection of the Agent.

A trigger with a Slack destination waits when its Agent has no authorized Slack connection, and the promotion still succeeds. When the Agent has a connection, one that has lost authorization or lacks the channel’s scopes fails promotion with 409 target_not_published, and a channel the app cannot use fails it with 404 channel_unavailable. A connection change during promotion returns 409 conversation_changed, and the request can be retried. See Triggers.