> ## Documentation Index
> Fetch the complete documentation index at: https://ara-90a60a07.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API

> Changes to the public /v3 REST API and its scopes.

Breaking changes to the published contract are gated in CI by an oasdiff check,
so anything listed here as removed or changed shipped deliberately.

## August 15, 2026 — Tightened CORS preflight header advertisement

* Cross-origin preflight responses now advertise only the request headers a browser client sends (`authorization`, `content-type`, `mcp-session-id`, `x-ara-org-slug`, `x-ara-trace-id`, `accept`). Operator and inbound-webhook signing headers, which are only used on server-to-server routes that never preflight, are no longer disclosed.

## August 15, 2026 — Secret access auditing and write-only immutability

* Secret access is now tracked in audit logs: decrypting secrets for a session run or
  brokered connector invocation emits a canonical `secret.accessed` audit event with
  the exact secret names and target run/connector scope.
* Workspace secrets support an immutable `revealable` flag (defaulting to `false` for
  new secrets). Write-only secrets (`revealable: false`) cannot be escalated back to
  revealable once stored, and their plaintext values are never disclosed on reveal endpoints.
* Relay egress observation mode is active for org-MCP and vendor broker relays,
  recording destination origin/host and allowlist verification telemetry on every outbound
  request without disrupting active integrations.

## August 12, 2026 — Per-organization memory for new cloud machines

* A cloud sandbox's writable filesystem is RAM-backed at roughly half its memory,
  so a box's memory is also its disk ceiling. `BLAXEL_SANDBOX_ORG_MEMORY_MB` now
  accepts `orgId:mb` pairs and sizes newly provisioned machines for those
  organizations, for repositories whose dependency tree does not fit the default.
* An explicit memory request is now clamped at the real 32 GB per-machine cap
  rather than the 16 GB large-repository tier. A request above the old ceiling
  was silently halved, so a machine asked for at 32 GB came up at 16 GB.
* This applies only when a machine is CREATED. A persistent box is reused by
  name and keeps the size it was born with, so an existing machine takes the new
  size at its next reset.

## August 12, 2026 — Retry a session on a different model over REST

* `POST /v3/organizations/{org}/sessions/{id}/messages` now accepts optional
  `model` and `reasoning_effort`, so a stalled or failed session can be retried
  on a different model through the REST API. Previously only the MCP tools could
  do this: REST accepted the fields and silently ignored them, returning `200`
  with the session still on its original model.
* A model override always starts a new continuation run, because a run's model is
  fixed at its first execution. Omitting both fields preserves today's behavior
  exactly.
* Both surfaces now validate through one resolver, so an id accepted on one is
  accepted on the other. An unusable override is refused with `400`
  (`invalid_model` / `invalid_reasoning_effort`) instead of being dropped.
* An override is refused with `409 model_override_requires_finished_session` while
  the session is still queued or running, because switching models requires a new
  continuation run and a live run would have kept its original model. Send the
  message without an override to steer a live session.
* An overridden model is credential-checked before the message is stored, so a
  model whose provider credential is disconnected returns the actionable
  `agent_model_key_missing` instead of a run that dies when a worker picks it up.

## August 11, 2026: Sessions cannot give an MCP server a command to run

* A running session can no longer create or update an organization MCP server that
  uses `stdio` transport, or that supplies a `command`. It gets
  `mcp_server_command_requires_human`. Add those in workspace settings instead.
* Everything else is unchanged. A session can still connect, update and disconnect
  `http` and `sse` servers, supply write-only secrets for them, toggle them on and
  off, and use every tool a configured server exposes. The one-click plugin flow is
  unaffected.
* External principals are unaffected: your API keys, the `ara` CLI, the Ara MCP
  server you connect from your machine, and workspace settings can all still add a
  stdio server.
* Why: a stdio server's `command` is executed by Ara inside your later sessions, and
  a new server applies to your workspace by default. Repo content and issue text can
  influence an agent, so choosing what gets executed belongs to a person.

## August 11, 2026: Sessions ask for secrets instead of storing them

* A running session can no longer store or delete a secret. `ara_secret_set` and
  `ara_secret_delete` are now available only to external principals: your own API
  keys, the `ara` CLI, and the Ara MCP server you connect from your machine. A
  session that tries gets `secret_write_requires_human`.
* Sessions can still LIST secret names, and still use every secret the workspace
  has. Only storing a value changed.
* When an agent needs a credential it does not have, it calls `request_secret`,
  which shows an "Add secret" card in the session with the exact variable name and
  why it is needed. You supply the value and it reaches the agent's next turn.
  Nothing about that flow changed; it is now the only route.
* Why: a stored secret applies to every later session in the workspace, so a
  session that can store one can change what all your future sessions trust. Repo
  content and issue text can influence an agent, so that decision belongs to a
  person. Existing secrets, and writes from the dashboard or your API keys, are
  unaffected.

## August 11, 2026: Reserved secret names, and mid-session secret delivery

* Secret writes now refuse names that control how a later process loads code or
  resolves the program it runs, because a stored secret is re-applied to every
  later session in the workspace. `POST /v3/organizations/{org}/secrets` returns
  `invalid_secret_name` for `BASH_ENV`, `ENV`, `PATH`, `NODE_OPTIONS`,
  `PYTHONPATH`, `RUBYOPT`, `JAVA_TOOL_OPTIONS`, git's own hooks such as
  `GIT_SSH_COMMAND` and `GIT_PAGER`, and anything starting with `LD_`, `DYLD_`,
  `GIT_CONFIG`, or `BASH_FUNC_`. Set these from your repository's own scripts
  instead, where they apply only to the commands you intend.
* A value already stored under one of those names is no longer applied to new
  sessions. Delete it and, if you still need it, set it from your repository
  setup instead. Deleting such a name continues to work.
* Names that point a tool at a different server are unaffected, so private
  registries and proxies keep working: `NPM_CONFIG_REGISTRY`, `PIP_INDEX_URL`,
  `HTTPS_PROXY`, and custom CA bundles are all still accepted.
* Adding, changing, or deleting a workspace secret now reliably reaches sessions
  that are already running, so an agent's next command sees it without waiting
  for a new session. Sessions using a persistent workspace previously kept the
  value they started with until their next session.

## August 10, 2026: Organization secrets and optional usage notes

* Secret list, set, and delete operations accept `scope: organization` for
  workspace-wide secrets. These secrets are available to runs throughout the
  workspace rather than being stored per repository.
* Secret writes accept an optional `note`. Use it to tell Ara or teammates how
  to use a secret, and include a repository name when the value is intended for
  one codebase. Lists return the note but never return the secret value.
* The former `repo` scope remains a compatibility alias. Its repository fields
  are accepted but ignored, and the stored secret is organization-wide. Add
  useful repository context to `note`. Personal `user` secrets are unchanged.
* `GET /v3/organizations/{org}/setup-helper` has been removed. Its deprecated
  empty compatibility payload no longer exists; start a repository-optional
  session and describe the device or codebase instead.
* The old repository Environment blueprint, image-build, required-plugin,
  authored setup-script, and readiness storage has also been removed. Connected
  repository access, workspace secrets, native `.ara/runbook.md`, and plugin
  connections remain independent capabilities that an agent can use during a
  task; none is a session-start prerequisite.
* The internal `environment_not_ready` run status has been retired. Historical
  rows are normalized to `infra_error`; new sessions are never blocked on
  repository setup, keys, plugins, or readiness metadata.

## August 9, 2026: Session-scoped environment variables on create

* `POST /v3/organizations/{org}/sessions` accepts an optional `env` object of
  environment variables for that session only. They are injected into the
  agent's shell alongside your repository and account secrets, override both
  on a name collision, and follow the session across follow-up messages
  (continuation turns see the same environment). Nothing is written to your
  organization's secret stores.
* Names must be valid shell environment names (`^[A-Za-z_][A-Za-z0-9_]*$`)
  and may not use reserved inference names such as `OPENAI_API_KEY` or
  `ANTHROPIC_API_KEY`; violations return `400 invalid_env`. At most 64
  variables, 32 KB per value, 256 KB total.
* Values are write-only: encrypted at rest, never returned by any read
  endpoint, and redacted from logs and transcripts, matching the secrets API's
  write-only philosophy.

## August 8, 2026: Guardrails gain merge-policy fields

* The `Guardrails` object on `GET`/`PUT`
  `/v3/organizations/{org}/repositories/{owner}/{repo}/guardrails` gains three
  optional fields: `auto_merge_protected_paths` (newline-separated globs whose
  matches require a standing human approval before an unattended merge),
  `auto_merge_max_changed_lines` (0 disables the size limit), and
  `auto_merge_delete_branch` (post-merge source-branch cleanup; forks and
  branches other open pull requests target are never deleted). Additive and
  optional, so existing clients are unaffected.

## August 8, 2026 — Point a session at a branch, a pull request, or a ref

* `POST /v3/organizations/{org}/sessions` accepts three new, mutually-exclusive
  start targets. Set at most one; setting more than one returns
  `400 conflicting_target`, and absence keeps the previous behavior (a fresh
  `ara/agent/*` branch off the default that opens a new pull request).
  * `branch`: check out an existing branch and commit onto it (created off the
    default branch if it does not exist yet).
  * `pr_number`: continue an existing GitHub pull request. The agent checks out
    its head branch and commits land back on the pull request, with no new one
    opened. The pull request is validated at create time: an unknown number is
    `404 pr_not_found`, a closed or merged one is `409 pr_not_open`, and a
    pull request whose head is on a fork is `422 pr_head_is_fork` (the app
    cannot push there). GitLab is not yet supported for this field.
  * `ref`: snapshot a commit SHA, tag, or branch. The agent starts a fresh
    working branch from that ref and opens a new pull request. The ref is
    resolved to an immutable commit at create time, so an unknown ref is
    `404 ref_not_found`, and abbreviated SHAs and moving branches/tags are
    pinned to the revision you requested rather than whatever the tip is when
    the run starts.
* A malformed or blank `branch` / `ref` returns `400 invalid_branch` /
  `400 invalid_ref`. A `branch` pointing at a protected branch (the default,
  `main`, or `master`) returns `422 branch_protected`, because the agent cannot
  push there.

## August 8, 2026: Loop-configured session creates fail fast while Loop is unavailable

* `POST /v3/organizations/{org}/sessions` with `long_running_enabled: true` now
  returns `400 invalid_request` at admission while Loop mode is unavailable on
  the current runtime. Previously the session was accepted and queued, then
  failed at execution with `harness1_pi_long_running_not_supported`.
* The request fields themselves are unchanged; nothing changes for sessions that
  do not set `long_running_enabled`.

## August 8, 2026 — Repo-scoped secret writes from an agent run require owner or admin

* An agent run writing a repository-scoped secret through Ara's own MCP surface
  now requires the run's user to be an owner or admin of the workspace, matching
  the rule already enforced on `/v3` and in the web app. A repo secret is pushed
  into every running session for that repository, so it is workspace
  configuration rather than a per-run setting.
* Listing secret names is unchanged, and a run can still manage the caller's own
  user-scoped secrets.

## August 7, 2026 — Attachments always download, and their content type comes from the file itself

* `POST /v3/organizations/{org}/attachments` no longer stores the `Content-Type`
  your multipart part declares. The stored type is derived from the file's own
  bytes: a real PNG, JPEG, GIF, WebP, WebM, or MP4 keeps its media type, and
  everything else is stored as `application/octet-stream`. The `content_type`
  field returned by the upload and list endpoints reports that stored type, so it
  always matches what a download actually returns.
* Downloads are now served with `Content-Disposition: attachment`, so a browser
  saves the file instead of rendering it. An HTML or SVG file uploaded as an
  attachment can no longer execute as a page on the storage host.
* Files uploaded before this change that were stored under a markup or script
  content type (`text/html`, `image/svg+xml`, `application/javascript`, …) are no
  longer downloadable: `GET /v3/organizations/{org}/attachments/{id}` answers
  `404`, and those entries come back from the list endpoint with `url: null`.
  Re-upload the file to get a working download URL. Documents, archives, text,
  and media uploaded earlier are unaffected.

## August 7, 2026 — Repository secret writes require owner or admin

* `POST` and `DELETE` on `/v3/organizations/{org}/secrets` with `scope: "repo"`
  now require the caller to be an owner or admin of the workspace, answering
  `403` otherwise. User-scoped secrets are unchanged: any member manages their
  own. A repo-secret write is pushed into every running session for that
  repository, so it is workspace configuration rather than a personal setting.
* The same rule already applied to repository-secret operations in the web app;
  this brings
  the public API in line with it. An integration that performs these writes
  needs a key minted by an owner or admin.

## August 7, 2026 — Failed-authentication throttling

* Repeated requests that present an invalid or expired credential from the same
  client are now throttled. After a burst of failed authentications the API
  answers `429` with a `Retry-After` header; back off for that long before
  retrying. This bounds API-key guessing and token enumeration. Successful
  requests and requests with no credential are unaffected, so ordinary
  authenticated traffic is never throttled.

## August 6, 2026: Credentials are no longer read from the URL query string

* The API no longer accepts a bearer credential passed as an `?access_token=`
  query parameter. Requests authenticate with the `Authorization: Bearer`
  header only; a token sent via the query string is ignored and the request
  answers `401` with `{"error": "missing_bearer"}`.
* URLs are routinely recorded in browser history, proxy logs, and `Referer`
  headers, so a credential placed there can leak outside the request
  (CWE-598). Header-only authentication closes that path.
* No published client or SDK ever sent tokens in the query string, so no
  integration changes are expected. The MCP OAuth compatibility endpoint,
  whose discovery flow requires a query credential, is unchanged.

## August 6, 2026 — Rate limiting on authentication endpoints

* The email-code sign-in and verification endpoints now enforce a per-client,
  per-account rate limit. When the limit is hit they answer `429` with a
  `Retry-After` header (seconds to wait); back off for that long before
  retrying. This guards accounts against code-guessing and send-spam and does
  not affect ordinary authenticated `/v3` traffic.

## August 1, 2026 — Provider connection routes retired

* The agent-auth provider-connection endpoints remain in the published contract
  but now answer `410` with
  `{"error": "provider_connections_temporarily_unavailable"}`. Provider
  credentials can no longer be submitted, stored, or used through the API. The
  affected routes are:

  ```
  POST /v3/organizations/{orgId}/agent-auth/azure-openai/connect
  GET  /v3/organizations/{orgId}/agent-auth/byok/usage
  POST /v3/organizations/{orgId}/agent-auth/byok/{provider}/connect
  DEL  /v3/organizations/{orgId}/agent-auth/byok/{provider}
  DEL  /v3/organizations/{orgId}/agent-auth/{provider}
  ```

* `GET /v3/organizations/{orgId}/agent-auth/models` stays live and is now the
  way to discover which models a workspace can run. Ara serves a curated model
  catalog rather than per-workspace provider credentials.

* `GET /v3/organizations/{orgId}/agent-auth/status` stays live.

## July 19, 2026 — System automations hidden by default

* `/v3` automation listings omit Ara's own system automations by default, so a
  client sees the automations its workspace authored rather than internal
  plumbing.

## July 15, 2026 — Automations resource and scopes

* Added an automation-centric resource with triggers as sub-resources:

  ```
  /v3/organizations/{orgId}/automations
  /v3/organizations/{orgId}/automations/{automationId}
  /v3/organizations/{orgId}/automations/{automationId}/triggers
  /v3/organizations/{orgId}/automations/{automationId}/triggers/{triggerId}
  ```

* Added the `automations:read` and `automations:write` API-key scopes that
  govern them.

## July 15, 2026 — Repository memory and notes

* Added workspace memory and knowledge notes to the public API:

  ```
  /v3/organizations/{orgId}/memory/notes
  /v3/organizations/{orgId}/memory/notes/{memoryId}
  /v3/organizations/{orgId}/knowledge/notes
  /v3/organizations/{orgId}/knowledge/notes/{noteId}
  ```

See the [API quickstart](/api-quickstart) to get a key, and the
[full endpoint reference](/api-reference) for the current contract.
