# API

## Current API

Implemented routes are:

- `GET /health`: process liveness only.
- `GET /api/v1/setup/status`: whether the one-time owner setup remains available.
- `POST /api/v1/setup/owner`: atomically creates the first workspace, owner, default roles and
  permissions, session, and audit event; requires the operator's out-of-band bootstrap capability
  and returns 409 after setup is complete.
- `POST /api/v1/auth/login`: generic credential failure, hashed server-side device session, and
  SameSite cookies. Redis enforces a source limit plus invalid-account counters that never block a
  correct credential.
- `POST /api/v1/auth/logout`: authenticated session revocation with double-submit CSRF validation.
- `POST /api/v1/auth/logout-all`: revokes every active device session for the current user/workspace.
- `POST /api/v1/auth/session/rotate`: replaces the current hashed session and CSRF credentials.
- `POST /api/v1/auth/sessions/{session_id}/revoke`: revokes one workspace/user-owned device session.
- `POST /api/v1/auth/mfa/setup` and `/mfa/verify`: password-confirmed TOTP enrollment followed by
  code verification; verification returns a one-time recovery-code set.
- `POST /api/v1/auth/mfa/recovery-codes` and `/mfa/disable`: reauthenticated recovery-code
  replacement or MFA removal with global session invalidation.
- `POST /api/v1/auth/password/change`: reauthenticated password replacement, optional MFA, reset-
  token invalidation, and global device-session invalidation.
- `POST /api/v1/auth/password-reset/confirm`: consumes an operator-issued, short-lived, one-use
  reset capability. Raw reset capabilities are never returned by a public request endpoint.
- `GET /api/v1/auth/me`: current user, workspace, and server-resolved permissions.
- `GET /api/v1/auth/sessions`: current user's device/session history without token material.
- `GET /health/database` and `/health/redis`: dependency readiness with redacted failures.
- `GET /health/readiness`: aggregate required-dependency readiness used by the container; detailed
  health routes are not edge-accessible.
- `GET /health/ai`: probes the isolated AI service and reports provider `configured`,
  `unconfigured`, or dependency `unavailable` without exposing credentials or provider errors.
- `GET /health/browser`: probes Computer Agent and reports `configured`, `unconfigured`, or
  `unavailable` without leaking the service token or worker error detail.
- `POST /api/v1/executions`: creates and audits a workspace-scoped planning record, asks the AI
  service for a typed plan, reauthorizes each tool in Core, and persists the validated plan and
  pending steps. Missing provider configuration returns 503 while preserving a durable `blocked`
  execution; it never fabricates a successful result.
- `GET /api/v1/executions`: lists at most the 100 newest executions in the authenticated workspace.
- `GET /api/v1/executions/{execution_id}`: returns a workspace-scoped execution and ordered steps;
  inaccessible and cross-workspace identifiers return 404.
- `POST /api/v1/executions/{execution_id}/cancel`: permission- and CSRF-protected, idempotent stop
  request for a non-terminal execution.
- `POST /api/v1/executions/{execution_id}/run`: permission- and CSRF-protected execution of a
  validated plan by its original actor. It rechecks current tool permission/policy and Core-owned
  arguments before every step, runs dependency-ready low-risk read steps with a timeout, persists
  verified results and audit checkpoints, and safely fails or observes cancellation. Replaying a
  succeeded read execution returns its existing result without rerunning tools.
- `GET /api/v1/agents` and `GET /api/v1/agents/{agent_id}`: workspace-scoped agent summaries and
  authorized current configuration, including explicit tools, permissions, and schedule.
- `POST /api/v1/agents`: CSRF-protected agent creation in disabled state. Grants must be known,
  possessed by the actor, and sufficient for every registered tool. Dedicated-computer creation is
  the default and additionally requires `computer.control`; administrator/full-system guests require
  approval authority. The VM operation is stored and audited before provider dispatch.
- `PATCH /api/v1/agents/{agent_id}`: updates configuration, creates a new durable version, and rejects
  manager cycles, cross-workspace references, unknown tools, and permission escalation.
- `POST /api/v1/agents/{agent_id}/status`: activates, disables, or archives an agent; autonomy level
  zero and computers without a stable provider-verified resource cannot be activated.
- `POST /api/v1/agents/{agent_id}/duplicate`: copies current configuration into a new disabled agent.
- `DELETE /api/v1/agents/{agent_id}`: deletes only an archived, unreferenced agent whose dedicated
  computer has been verifiably destroyed, and audits its ID and final version.
- `POST /api/v1/agents/{source_agent_id}/delegations`: records an auditable requested delegation
  whose scope is limited to the intersection of the actor and both active agents. It does not yet
  enqueue or claim completion of delegated work.
- `GET /api/v1/model-profiles`: lists workspace-owned routing profiles together with the AI
  service's honest `configured`, `unconfigured`, or `unavailable` provider state.
- `POST /api/v1/model-profiles` and `PUT /api/v1/model-profiles/{profile_id}`: CSRF-protected owner
  administration of provider/model routing metadata. These endpoints never accept or return provider
  credentials.
- `DELETE /api/v1/model-profiles/{profile_id}`: deletes only an unreferenced workspace profile;
  active agent references fail closed with a conflict.

### Computer control plane

- `GET /api/v1/computers`: lists first-class per-agent VMs and the honest compute-provider state.
- `GET /api/v1/computers/templates` and
  `PUT /api/v1/computers/templates/{template_id}`: list Linux/Windows templates and bind a verified
  provider image reference. Windows templates require an explicit license confirmation.
- `GET|PUT /api/v1/computers/limits`: read or update workspace computer count, concurrently active,
  CPU, RAM, and disk ceilings. Limits cannot be lowered below current usage.
- `GET /api/v1/computers/{computer_id}`: returns the VM, assigned agent, network policy, snapshots,
  recent operations, and latest metrics without returning provider credentials/control endpoints.
- `POST /api/v1/computers/{computer_id}/provision`: clone the configured OS template through the
  restricted provider gateway. Requires CSRF and `Idempotency-Key`.
- `POST /api/v1/computers/{computer_id}/actions/{start|stop|restart|pause|resume|destroy|refresh}`:
  durable, idempotent, audited VM lifecycle. Provider state is read after mutation for verification;
  ambiguous outcomes remain `unknown`. Destroy also requires approval authority and exact-name
  confirmation.
- `PUT /api/v1/computers/{computer_id}/network-policy`: changes internet/LAN/platform/other-agent
  egress only while stopped or suspended. Host-management access is not accepted and is constrained
  off in the database.
- `POST /api/v1/computers/{computer_id}/snapshots` and
  `POST /api/v1/computers/{computer_id}/snapshots/{snapshot_id}/restore`: create or explicitly
  confirm/restore provider VM snapshots.
- `POST /api/v1/computers/{computer_id}/resize`: confirmed stopped/suspended CPU/RAM/disk resize;
  workspace limits apply and disk shrinking is rejected.
- `GET /api/v1/computer/status`: durable emergency-stop state plus honest worker state.
- `GET|POST /api/v1/computer/profiles`, `PUT /api/v1/computer/profiles/{profile_id}`, and
  `POST /api/v1/computer/profiles/{profile_id}/revoke`: workspace-scoped browser-profile
  administration inside the assigned VM; storage keys and profile contents are never returned.
- `GET|POST /api/v1/computer/sessions` and `GET /api/v1/computer/sessions/{session_id}`: create/list/
  inspect durable sessions, actions, checkpoints, artifacts, and the active controller lease.
- `POST /api/v1/computer/sessions/{session_id}/actions`: validated DOM-first action. Requires CSRF
  and `X-Idempotency-Key`; exact replay returns the stored response and a changed payload conflicts.
- `GET /api/v1/computer/approvals` and
  `POST /api/v1/computer/actions/{action_id}/decision`: list/decide browser approvals. Approval is
  bound to the exact canonical request; changed or unavailable raw payloads must be re-proposed.
- `POST /api/v1/computer/sessions/{session_id}/takeover` and `/return-control`: atomically fence AI,
  assign the current user a human lease, then snapshot/re-observe and issue a fresh AI fence.
- `POST /api/v1/computer/sessions/{session_id}/human/pointer` and `/human/keyboard`: inputs accepted
  only from the exact active human controller. Sensitive keyboard text is redacted from audit data.
- `GET /api/v1/computer/sessions/{session_id}/frame`: no-store JPEG live frame proxied through Core.
- `GET /api/v1/computer/artifacts/{artifact_id}`: workspace-authorized screenshot retrieval with
  worker path containment plus SHA-256/size verification and restrictive response headers.
- `POST /api/v1/computer/sessions/{session_id}/pause`, `/resume`, `/stop`, and `/recover`: explicit
  lifecycle operations. Recovery reopens the same persistent profile and never retries a write.
- `POST /api/v1/computer/emergency-stop` and `/emergency-resume`: durable workspace stop/resume.
  Stop reports verified and unverified worker outcomes; resume does not restart any session.
- `POST /api/v1/computer/actions/{action_id}/reconcile`: authorized human evidence records a final
  result for an interrupted write whose outcome is `unknown`; it does not automatically resume.

`GET /health` returns `{"status":"ok","service":"core-api"}` and proves only that the FastAPI
process can respond. It does not check PostgreSQL, Redis, AI providers, or browser health. Password
General integrations and most later product APIs are not implemented.

The current middleware accepts `X-Request-ID` or generates a UUID and returns it in the response.
Application `AppError` exceptions use:

```json
{
  "success": false,
  "error": {
    "code": "STABLE_MACHINE_CODE",
    "message": "Human-readable message.",
    "request_id": "correlation-id"
  }
}
```

Validation and unhandled errors are normalized to this contract without returning internal details.

## Target public contract

Product routes are versioned under `/api/v1`. JSON uses snake_case, UTF-8, RFC 3339 timestamps with
offsets, and opaque string identifiers. OpenAPI is the canonical machine-readable HTTP contract and
must be checked for unintended breaking changes in CI.

Authenticated workspace requests derive workspace access from the session and membership. If a
workspace selector is needed, it selects among memberships; it does not grant access. Resource
responses do not expose encrypted secrets, password material, internal prompts, or private model
reasoning.

Success responses use a stable data envelope for product APIs:

```json
{"success": true, "data": {}, "meta": {"request_id": "..."}}
```

Collections use cursor pagination. Filters and sorting are allow-listed. Errors use stable codes;
clients must not parse message text. Expected status mappings include 400 invalid operation, 401
unauthenticated, 403 unauthorized, 404 inaccessible/not found, 409 state conflict or idempotency
conflict, 422 validation failure, 429 throttled, and 503 dependency unavailable.

## Mutation safety

External-side-effect endpoints require an idempotency key. Browser actions use
`X-Idempotency-Key`; VM provider operations use `Idempotency-Key`. The key is scoped to the workspace/resource and
normalized action, retained long enough to cover provider retry windows, and returns the original
result for a matching replay. Reusing a key with a different request is a conflict.

An accepted operation is not equivalent to a completed external action. Long-running commands return
an execution/action resource whose state can be polled or streamed. Canonical states distinguish
`queued`, `running`, `awaiting_approval`, `succeeded`, `failed`, `cancelled`, and `unknown`. Success is
set only after required verification.

Approval decisions use optimistic concurrency/version checks so an expired, edited, rejected, or
already-consumed request cannot be approved by a stale client.

## Target resource groups

The following paths describe contract ownership, not implemented endpoints:

- Remaining `/api/v1/auth`, `/sessions`, `/workspaces`, `/memberships`: identity and workspace access.
- `/api/v1/roles`, `/permissions`: RBAC administration.
- Remaining agent version/delegation lifecycle and `/agent-templates`: agent history and templates.
- Remaining model-profile capability/fallback administration; the initial OpenAI routing catalogue
  is implemented without secret storage.
- Remaining `/api/v1/executions` lifecycle and `/actions`: command execution and verified action state.
- `/api/v1/approvals`: policy approval lifecycle.
- `/api/v1/integrations`: configuration and honest connection health.
- `/api/v1/audit-events`: authorized, filtered audit history.
- `/api/v1/health/readiness`: required internal dependency readiness.

Domain resources for contacts, CRM, tasks, memory, communications, general files, calls, and
automations are added only with their implementations. The initial computer resource group is
implemented as listed above.

## Internal service contracts

Internal HTTP commands are versioned independently and authenticated as service identities. Every
command carries workspace, actor, request, execution, action, and policy/grant identifiers. Workers
receive a narrowly scoped, expiring action grant; they do not independently raise autonomy or infer
permissions.

The initial AI service exposes these internal-only routes on the application network:

- `GET /health`: liveness plus honest OpenAI provider configuration state; no service token needed.
- `GET /v1/tools`: service-token-authenticated public contracts for the trusted tool registry.
- `POST /v1/plans`: service-token-authenticated typed plan generation. The request carries
  execution/workspace/actor identifiers, instruction, an explicit tool allowlist, and a one-way
  safety identifier. The result is schema-validated, restricted to registered tools, and validated
  again by Core authorization before persistence.

The AI service only plans. It does not execute tools, access the Core database, raise permissions,
or report an execution as succeeded; the Core runtime owns the implemented read-tool execution and
verification boundary.

The Computer Agent exposes internal-only service-authenticated routes:

- `GET /health`;
- `POST /v1/sessions` and session `pause`, `resume`, `stop`, and `snapshot` commands;
- `POST /v1/sessions/{session_id}/actions` for typed DOM-first actions;
- `POST /v1/sessions/{session_id}/human/pointer` and `/human/keyboard`;
- `POST /v1/sessions/{session_id}/frame`; and
- `GET /v1/artifacts/{workspace_id}/{session_id}/{artifact_id}`.
- `DELETE /v1/artifacts/{workspace_id}/{session_id}/{artifact_id}` for retention cleanup.

Every worker route except liveness requires the static service identity plus a short-lived Ed25519-
signed capability bound to audience, key ID, exact scope, request ID, and applicable workspace,
session, and fencing token. Mutating commands also carry fencing and replay state. The worker never
makes authorization or approval decisions.

Asynchronous event envelopes include:

```json
{
  "event_id": "...",
  "event_type": "execution.requested",
  "schema_version": 1,
  "occurred_at": "...",
  "workspace_id": "...",
  "request_id": "...",
  "execution_id": "...",
  "data": {}
}
```

Events are published from a transactional outbox and delivered at least once. Consumers deduplicate
by `event_id`; ordering assumptions must be aggregate-specific and explicit. Sensitive fields are
minimized, encrypted, or referenced rather than broadcast.

## Realtime and webhooks

Future execution/status streams authorize both connection and each subscribed workspace resource.
Reconnect uses a cursor; clients must tolerate duplicate status events.

Incoming webhooks require provider-specific signature verification, timestamp/replay validation, and
provider event deduplication before processing. Outgoing webhooks are signed, retried with backoff,
and expose delivery history without leaking their signing secret.
