REST API
Terminal retirement — publication boundary, 2026-10-23
Section titled “Terminal retirement — publication boundary, 2026-10-23”Backend/Admin terminal retirement is deployed on GKE: new interactive terminals and relay operation are disabled, while command/script Remote Actions and protected read-only history remain. The repository also removes the native PTY runner; no new installed-desktop release was published as part of CR0. Explicit Redis resource cleanup remains separate. See the retirement plan and publication evidence; earlier local implementation descriptions below are historical.1
Contract authority
Section titled “Contract authority”All application routes are prefixed by /api/v1. Runtime controllers and their Zod schemas are the executable contract; the Swagger document exposed by the running backend is the most detailed generated view. This page describes stable route families and security expectations rather than duplicating every payload.
Route families
Section titled “Route families”| Family | Responsibility | Expected authorization |
|---|---|---|
/auth |
Native password/TOTP registration, login/recovery, optional GitHub PKCE, refresh, logout and recent-auth grants | Public bounded challenge/exchange where applicable; persisted current session for identity endpoints |
/organizations |
Native organizations, invitations, grant-backed membership and settings | Current member; admin/owner for mutation |
/projects |
Native projects, detail, workflow, optional provider synchronization and guarded lifecycle | Project member; admin/owner for administrative mutation |
/work-items |
Provider-neutral work items, iterations, transitions and optional write-back | Project member; mutation additionally constrained by integration policy |
/time-entries |
Start, stop, manual entries and history | Entry owner and accessible project |
/admin/orgs/:orgId/customers, /customer-projects, /customer-audit-events |
Bounded customer lifecycle, contacts, environments, many-to-many engagements and metadata-only audit | Current member for reads; admin/owner for mutation |
/projects/:projectId/work-items/:workItemId/customer-visibility |
Atomic explicit customer visibility allowlist | Project administrator |
/time-entries/:id/customer-allocations |
Revisioned conservative customer-second allocation | Project administrator and entry scope |
/agent-ingestion, /admin/orgs/:orgId/agent-* |
Installation-bound ingestion plus agent policy, bindings, live/session/chat/allocation queries and export/deletion governance | Installation proof for ingest; organization member/admin and content capability according to route |
/admin/orgs/:orgId/report-*, /report-template-edit-sessions |
Definitions/templates/bindings, signed edit callbacks, runs/artifacts/approval, delivery, schedules, portable bundles and storage reconciliation | Organization administrator; callback requires a purpose/document/session-bound expiring token |
/screenshots |
Presign, register, temporally filter, read, delete and page-bounded bulk delete | Entry/screenshot owner or authorized organization admin |
/activity |
Snapshots, app usage and heartbeat | Entry owner; project and tenant consistency required |
/admin |
Organization analytics, delivery metrics, integrations, Hubstaff import, compliance, Local AI and Remote Actions control plane | Current organization admin/owner with resource-level tenant scope; signed-action launch/transcript disclosure retain recent-auth, while terminal creation/connection is retired locally |
/desktop/installations |
Shared installation registration, signed heartbeat, revocation and device-scoped compliance | Current user plus Ed25519 installation proof; admin/owner for inventory and revocation |
/ai |
Rules/local-pack inference, pack resolution/download tickets and signed install/inference reports | Authenticated user plus organization scope; installation proof for device state |
/remote-actions |
Device command/script claim/report and retired-terminal compatibility | Installation proof, leased execution claims and feature policy; terminal polling empty and control terminates |
/updates |
Desktop update publish/retrieve | CI upload authority; controlled client download |
Authentication exchange
Section titled “Authentication exchange”Native email/password is the first supported identity path and may require TOTP according to the user policy. Optional GitHub authentication uses PKCE: the backend atomically consumes state and exchanges only one-time codes. Both paths issue the same persisted MonStaff session pair. POST /auth/refresh rotates the refresh token; reuse revokes the session family. POST /auth/logout revokes the current persisted session.
The canonical GitHub callback is GET /auth/identities/github/callback. GET /auth/github/callback remains a compatibility alias for the callback registered on the existing GitHub OAuth App; both paths execute the same validated callback handler.
A verified GitHub identity is reconciled into each active organization GitHub connection as a connection-scoped provider user link. Reconciliation runs both when OAuth completes and when an organization connection is created or reconnected, so GitHub issue assignees resolve to stable MonStaff user IDs regardless of operation order. Ambiguous or conflicting mappings are rejected rather than inferred from email.
With an active organization connection, GET /integrations/github/repositories and GET /integrations/github/members expose bounded provider discovery. Repository discovery reads the explicit organization catalog when the connection has an organization key, preventing accessible repositories owned elsewhere from leaking into the import selector.2 Administrative repository import creates or reactivates native projects and idempotent repository links, then may queue synchronization. Administrative member import revalidates selected GitHub organization members before creating stable GitHub identities, connection-scoped user links and MEMBER-only GITHUB_SYNC grants. Batches are limited to 100 resources and member import never infers email identity.3
Legacy possession-polling/device-token routes are not part of the current contract.
Project work-item lists accept an allowlisted canonical state filter in addition to provider workflow status, type, iteration, assignee and text filters. The desktop client uses state=OPEN for project-scoped selection; /work-items/mine remains the narrower assigned-open contract.4
GET /projects/:id returns project-centered customer engagements and a server-derived deletion-readiness summary. DELETE /projects/:id archives; DELETE /projects/:id/permanent is a distinct administrator-only operation that succeeds only when the project is already archived and every persisted project relation is empty. The mutation repeats the empty-relation predicates atomically and returns 409 when state or links prevent deletion.5
Screenshot lists accept ISO from and to capture bounds. POST /screenshots/bulk-delete accepts one to 24 unique UUIDs, applies the same owner scope and durable object-deletion lifecycle as the single-item route, and returns completed and failed ID sets so clients can represent partial cleanup honestly.6
Asynchronous jobs
Section titled “Asynchronous jobs”Long import and integration synchronization requests return HTTP 202 with a persisted job resource. Clients poll the matching status route and may request cancellation; a worker owns the job only for its renewable lease. Active target/fingerprint constraints deduplicate concurrent work. Hubstaff supports OAuth-backed segmented jobs and a bounded checksum-addressed CSV preview/start fallback.
Retriable writes
Section titled “Retriable writes”Timer, activity and screenshot write routes accept a UUID idempotency key. Replaying the same operation returns the recorded outcome; conflicting reuse is rejected. Clients must not assume that a transport timeout means the write did not commit.
Response conventions
Section titled “Response conventions”Successful responses commonly wrap the payload in data; list endpoints may include pagination. Application errors are translated to status, error and message fields. Exact shapes must be inferred from controller schemas/shared types until generated OpenAPI is committed or tested.
Security requirement
Section titled “Security requirement”An authenticated route must still load the addressed resource and verify ownership, role and tenant. Do not authorize by accepting organizationId, projectId, timeEntryId or storagePath from the client without a server-side relationship check.
Recent worked projects
Section titled “Recent worked projects”Locally implemented after 0.3.27: authenticated GET /projects/recent returns { data: Project[] } with at most five distinct projects, ordered by the caller’s latest time-entry startedAt descending (project ID breaks ties). The query includes running/manual entries, excludes superseded and projectless entries, and requires an active project plus active organization membership with an unrevoked grant. It scans the full personal history through database aggregation, independent of project updatedAt and other users’ work. No new schema migration; backend deployment remains pending.7
Administrator bulk reset (local implementation)
Section titled “Administrator bulk reset (local implementation)”Time Activity and Delivery Sessions expose administrator/owner bulk deletion. Selecting a complete page offers selection of all matching results across pages, using current filters and an explicit count confirmation. Requests are sent in batches of at most 100. Time-entry batches reject running and automatically allocated/superseded entries; screenshot object cleanup is durable and asynchronous. Session batches queue telemetry deletion and preserve official hours. The internal run ID is resolved to the actual external session key, owner and provider; configured ClickHouse removal precedes canonical deletion. New or in-flight telemetry may recreate sessions. Publication and live worker/ClickHouse verification remain unperformed.8
POST /admin/orgs/:orgId/time-entries/bulk-delete accepts { ids }; POST /organizations/:orgId/agent-sessions/bulk-delete accepts { ids, reason }. Each requires organization administrator authority and 1–100 unique UUIDs. Session deletion is queued; a successful response is not a completion receipt.8
Update publication compatibility (locally qualified)
Section titled “Update publication compatibility (locally qualified)”The CR2 compatibility change, not yet deployed, adds GCS staging to POST /updates/publish-url/:filename. When completionRequired is true, PUT to uploadUrl using every returned headers field, then call POST /updates/publish-complete/:filename with { completionToken } and the existing x-upload-token. The signed token binds filename, size, SHA-256 and expiry; the backend verifies bytes before publication. MinIO direct signed uploads and desktop downloads preserve their existing contract.
The final local report-upload correction signs metadata headers explicitly for report template and bundle uploads; existing Admin clients already send x-amz-meta-sha256. Fourteen GCS checks in the actual image and ten MinIO checks pass. Actual browser acceptance was explicitly deferred by the operator; remote qualification and final rollout remain pending.
Footnotes
Section titled “Footnotes”-
Local interactive-terminal and Redis retirement. ↩
-
GitHub organization repository discovery scope correction. ↩
-
GitHub native project and member import. ↩
-
Desktop work-item visibility repair. ↩
-
Project detail, customer association and safe permanent deletion. ↩
-
Desktop screenshot library temporal filtering and bulk deletion. ↩