Skip to content

HTTP API reference ​

Use this reference to find HTTP routes, their owning services, and their authorization requirements. An owner service handles an operation's authoritative state and authorization. A native route is mapped by an owner service; it is not public through the Gateway unless the table lists a Gateway path. These tables describe source mappings, not deployed addresses.

For request and response contracts, see service contracts. For provider setup, see Configure providers. For runtime settings, see Runtime configuration. The Gateway's GET /openapi/v1.json returns the versioned public schemas, which the MCP tools reference uses.

The checked-in release/Kustomize composition still includes MCP compatibility image, workload and ingress resources. Their presence does not make MCP a supported product or acceptance surface. Supported client paths are Gateway/API, browser and native .NET CLI. Outbound remote MCP connections are separate.

CLI operation discovery ​

The native agentweaver api operations, api describe, and api invoke commands use the Gateway's currently served GET /openapi/v1.json document; they do not maintain a separate route inventory or apply the retained MCP compatibility adapter's admission filter. Supported public operations remain in the CLI catalog even when the adapter does not expose them. The direct agentweaver rest command can address an uncatalogued path on the same Gateway origin, but this does not add that route to the catalog or prove operation/API parity. See the CLI guide.

Identity Connection browser BFF routes, including /api/connections/..., are not in the Gateway OpenAPI catalog and are not part of CLI parity. The CLI therefore does not provide complete browser or BFF parity. For the CLI commands, authorization, and current distribution status, see the Agentweaver CLI guide.

Periodic issue sync ​

These routes do not require a run. They require an authenticated project Owner with api.read and projects.admin; run-bound and purpose-bound tokens are rejected. Gateway exposes them under /api/v1. The retained MCP compatibility adapter prefixes its generated tool operation IDs with agentweaver_; this is source behavior, not a supported product use path.

Gateway routeNative ownerOperation ID
GET /api/v1/projects/{projectId}/issue-syncOrchestrator GET /api/projects/{projectId}/issue-sync/readIssueSync
PUT /api/v1/projects/{projectId}/issue-syncOrchestrator PUT /api/projects/{projectId}/issue-sync/configureIssueSync
POST /api/v1/projects/{projectId}/issue-sync/grantsIdentity same path without /v1, with trailing slashcreateIssueSyncGrant
GET /api/v1/projects/{projectId}/issue-sync/grants/{grantId}Identity same path without /v1readIssueSyncGrant
POST /api/v1/projects/{projectId}/issue-sync/grants/{grantId}/revokeIdentity same path without /v1revokeIssueSyncGrant

Create a grant with { "selectionCode": "<fresh Identity repository selection code>" } after selecting the project's connected GitHub App repository. Identity consumes the owner-bound selection once and returns { grantId, project: { projectId, tenantId, creatorId, connectionId, repository: { owner, name } }, active }. No credential appears in public responses. Secret-authenticated repositories cannot borrow run-token redemption for background sync.

Configure with { expectedRevision, settings: { enabled, grantId, intervalSeconds, maxItems, maxCycleSeconds } }. expectedRevision is zero on creation and the returned revision on edits. intervalSeconds is 30-86400, maxItems 1-100, and maxCycleSeconds 5-120 and no larger than the interval. A cycle reads one page of at most maxItems issues and reconciles at most maxItems tasks, within its deadline. Configuration and status return projectId, tenantId, revision, settings, safe grantProof, nextCycleAt, nullable lastCycleAt, status, nullable errorCode, importPage, and taskCursor. An unconfigured project returns 404, not fabricated status. Concurrent configuration/cycles return 409.

Owners may disable sync even after its grant is revoked or the repository is unselected. Revocation returns { "revoked": true } and prevents the next cycle; in-flight cycles also revalidate before effects. Only the creator or a current tenant administrator can revoke a grant. Grant reads validate the original creator's current authority. A changed repository does not reuse old mappings.

Status is configured, disabled, running, succeeded, or failed. Failure codes include issue_sync_grant_revoked, issue_sync_creator_not_owner, issue_sync_repository_not_selected, issue_sync_cycle_timeout, provider-specific issue_sync_provider_*, and issue_sync_create_outcome_pending. Failures preserve confirmed progress and retry next cycle; uncertain external writes are not reported as success. See reconciliation and recovery.

Private routes are not Gateway/MCP tools. Identity POST /internal/issue-sync/grants/{grantId}/token and POST /internal/issue-sync/grants/{grantId}/validate accept only the configured Orchestrator mTLS peer. Projects POST /internal/issue-sync/project-authority accepts only the Identity mTLS peer and { projectId, tenantId, creatorId }. Projects' authenticated GET /api/projects/{projectId}/issue-sync-owner and issue-sync-authority provide live owner and selected-repository proofs. The native GET /api/projects/{projectId}/issue-sync-grant-revocation supplies current creator/admin revocation evidence without granting worker authority. These routes never create run or secret grants. Webhooks and conflict prompts are out of scope.

How to read this reference ​

Some tables list a route prefix and its suffixes. Append a suffix to the prefix to form the full path. A route constraint such as :guid or :long describes the accepted value; it is not part of the value you send. An empty suffix adds no slash.

The Gateway column shows whether the Gateway exposes the same suffix under the versioned prefix. No means the route is native-only. Where a table notes that the Gateway omits a trailing slash, use the path shown in the Gateway column.

Authorization key ​

All protected routes validate the configured issuer, audience, and token lifetime. Scopes do not replace current roles, owner state, or immutable bindings.

KeyRequirement
PublicNo bearer required. Callback routes still validate their protocol transaction.
BearerAuthenticated Broker bearer; additional owner checks are described by the operation.
Readapi.read, active tenant membership, and current project read authority: TenantAdmin, Owner, Contributor, or Viewer. Token bindings must match the resource.
Adminapi.read and projects.admin, active membership, and TenantAdmin or project Owner authority.
Selectionapi.read and projects.orchestrator, current project Orchestrator assignment, and matching project/run binding.
CoordinationExact project/run bearer with api.read and projects.orchestrator, matching owner audience, and a current accepted Projects selection.
JournalAuthenticated signed project/run scope, current Sessions provider binding, and owner-authorized journal access. Writes also require the appropriate owner admission.
Private KnowledgeCurrent AccessPrivateKnowledge permission plus ReadRunSelection authority. Run-scoped routes use the accepted run Memory selection; project-wide search requires an unbound token and uses only existing run-provider bindings. The permission comes from Projects, not record content.
RuntimeAuthenticated bearer plus exact current runtime registration, placement, purpose, proof, or receipt required by that operation. These are not ordinary user write APIs.
Environment readBearer plus current ReadProjects authority and matching tenant/project/run binding.
Environment writeBearer plus current WriteProjects authority, matching owner binding, and operation-specific fences. Operations that read accepted selections also require ReadRunSelection. Projects does not grant WriteProjects to run-bound callers.
BrowserBroker local session cookie; mutations require antiforgery protection.

The optional X-Agentweaver-Tenant header is a selector. Owners validate it; clients cannot use it to grant membership or change identity.

Gateway ​

Environment discovery and recovery ​

The Gateway forwards these routes to the configured Environment owner. All routes require a Broker bearer and a matching tenant. Any project or run binding in the token must match the route. Environment checks current authority and generation fences; Gateway authentication alone does not grant access. The routes are not MCP tools.

MethodGateway pathOperation IDOwner authority
GET/api/v1/projects/{projectId}/runs/{runId}/environmentslistRunEnvironmentsWriteProjects and ReadRunSelection
GET/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/lifecyclereadEnvironmentLifecycleReadProjects
GET/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/workspace-volumeslistEnvironmentWorkspaceVolumesWriteProjects and ReadRunSelection
GET/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/workspace-volumes/{volumeId}readEnvironmentWorkspaceVolumeReadProjects
POST/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/workspace-volumes/{volumeId}/bindbindEnvironmentWorkspaceVolumeWriteProjects and ReadRunSelection
POST/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/workspace-volumes/{volumeId}/unbindunbindEnvironmentWorkspaceVolumeWriteProjects and ReadRunSelection
POST/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/workspace-volumes/{volumeId}/releasereleaseEnvironmentWorkspaceVolumeWriteProjects and ReadRunSelection
POST/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/sandbox/provisionprovisionEnvironmentSandboxWriteProjects and ReadRunSelection
GET/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/sandboxreadEnvironmentSandboxWriteProjects and ReadRunSelection
POST/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/sandbox/abandonabandonEnvironmentSandboxWriteProjects and ReadRunSelection
POST/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/sandbox/reconcilereconcileEnvironmentSandboxWriteProjects and ReadRunSelection
GET/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/sandbox/v1/operations/{operationId}/provider-attemptsreadEnvironmentSandboxProviderAttemptsWriteProjects and ReadRunSelection
GET/api/v1/projects/{projectId}/runs/{runId}/environments/{environmentId}/sandbox/v1/late-resource-cleanupsreadEnvironmentSandboxLateResourceCleanupsWriteProjects and ReadRunSelection

The two list operations accept limit (default 25, range 1 through 100) and an opaque cursor. Environment-list cursors are bound to the tenant, project, and run. Workspace-volume cursors are also bound to the Environment and its current lifecycle generation. A cursor for another scope is rejected. Sandbox inspection requires the networkPolicyGeneration query value. Reconciliation accepts the same value as optional input. The bind, unbind, release, provision, and abandon requests are limited to 16 KiB. A larger request returns 413 Payload Too Large before the Gateway forwards it. Environment applies the same limit at its owner routes. Reconcile has no request body.

Recovery writes use the expected resource, data, transition, or provider generations in the request. Repeat an uncertain operation with the same idempotency key and generation values. Do not start a replacement operation while the saved operation is pending or unresolved. A 202 Accepted response means the owner recorded work; it does not mean that provider work completed. The Environment Sandbox architecture describes the durable fences and recovery behavior.

Project backlog content ​

The Orchestrator owns project backlog tasks independently of runs. The Gateway forwards the tenant selector and exposes these versioned operations:

MethodGateway pathAuthority
GET/api/v1/projects/{projectId}/backlogCurrent ReadProjects
POST/api/v1/projects/{projectId}/backlog/tasksCurrent WriteProjects
POST/api/v1/projects/{projectId}/backlog/ready-allCurrent WriteProjects
PUT/api/v1/projects/{projectId}/backlog/tasks/{taskId}/contentCurrent WriteProjects
PUT/api/v1/projects/{projectId}/backlog/tasks/{taskId}/positionCurrent WriteProjects
PUT/api/v1/projects/{projectId}/backlog/tasks/{taskId}/stateCurrent WriteProjects
POST/api/v1/projects/{projectId}/backlog/tasks/{taskId}/archiveCurrent WriteProjects
DELETE/api/v1/projects/{projectId}/backlog/tasks/{taskId}Current WriteProjects
PUT/api/v1/projects/{projectId}/backlog/tasks/{taskId}/dependencies/{prerequisiteTaskId}Current WriteProjects
DELETE/api/v1/projects/{projectId}/backlog/tasks/{taskId}/dependencies/{prerequisiteTaskId}Current WriteProjects

Task deletion is rejected when another task depends on it, when it came from an accepted work plan, when it has a repository issue sync receipt, or while that project's issue sync cycle is active. Once queue positions are installed, a successful deletion compacts the task's state queue in the same transaction.

The native paths replace /api/v1 with /api. Reads require api.read. Writes also require projects.admin and project Owner or tenant administrator authority. Run-bound and purpose-bound tokens cannot use these routes. An optional project binding must match the route. The bearer must include the Orchestrator and Projects audiences. The owner rechecks membership and role revisions after acquiring the graph lock and again before committing every write.

The Orchestrator locks the project's backlog_projects row before reading or mutating its graph. Task and dependency changes serialize through that project mutex and the expected graph revision; dependency rows are read under the mutex and changed only by insert or delete. The planned runtime role therefore needs no UPDATE privilege on backlog_dependencies.

Capture accepts taskId, expectedGraphRevision, and content. Content contains title, optional description, lifecycle (open or closed, default open), and optional repositoryIssue. A title has 1-512 characters and no control characters. A description has at most 65,536 characters and no NUL character. The owner trims the title. Content replacement also requires expectedTaskRevision. Both operations return the current project graph; stale revisions and duplicate repository issues return 409 with typed backlog issues. An unchanged replacement preserves both revisions. The initial task revision is 0; callers must accept and pass that value as expectedTaskRevision until an edit advances it.

repositoryIssue contains a provider catalog ID (providerId), a typed repository with owner and name, and a positive issueNumber. Repository names are normalized to lowercase. A project can link an issue to only one task, including archived tasks. Issue-sync clients read the graph to reuse that identity on repeated import; a conflicting insert does not create a second task. These routes do not call the repository provider or synchronize issues.

Closing a ready task moves it back to backlog. A closed task cannot become ready or receive a new claim. Closing a claimed task retains its existing claim and run ownership; it does not cancel execution. Reopening does not schedule work. Archive remains separate from open/closed lifecycle. Historical ID-only tasks retain an empty title until edited.

State writes can move an unclaimed open task between backlog and ready; only an atomic claim can set claimed. Dependency writes reject self-links, cross-project links, missing tasks, and cycles. Adding an existing dependency succeeds as a no-op and does not change the graph revision. Marking a task Ready queues it but does not prove its prerequisites are complete. A claim checks current prerequisite execution and output evidence again and returns typed blockers when work is not eligible. Archive and dependency changes use the same graph lock and revision checks as task edits.

Position writes use a zero-based insertion index in the complete state queue after removing the moved task. Hidden archived or closed tasks still occupy queue slots, and each successful move reindexes affected queues. Insertion is unavailable until migration 035 installs persisted positions.

Each task snapshot includes a zero-based position within its queue. A position write sends state, position, expectedGraphRevision, and expectedTaskRevision. The owner reorders the queue under the graph lock and advances revisions for every task whose state or position changes. Batch-ready sends expectedGraphRevision and moves open, unarchived tasks without a pending automation invocation from Backlog to Ready in one graph change. Prerequisites are still checked when a run claims a task.

Delete sends expectedGraphRevision and expectedTaskRevision. The owner rejects claimed, archived, or provisional tasks, tasks that have dependents, and tasks promoted from an accepted work plan. It removes the deleted task's own prerequisite links in the same transaction.

Migration 026_backlog_task_content.sql stores editable content. Migration 035_backlog_task_queue_position.sql stores queue order and adds the index used to read it. The new owner image accepts the complete schema before 035 is applied, but position and batch-ready writes return 503 until then. Both migration versions, the backlog delete grant, and the PostgreSQL plan hash are recorded in the reviewed plan; none is applied to a live database. MCP discovers these operations from the Gateway catalog. The retained Board supports queue order, batch-ready, state, archive, and prerequisite actions; it does not start a run.

Repository team sync ​

The Gateway exposes an explicit preview-and-commit operation for the current project team:

MethodGateway pathNative owner pathOperation ID
GET/api/v1/projects/{projectId}/team/syncOrchestrator GET /api/projects/{projectId}/team/syncreadProjectTeamSync
POST/api/v1/projects/{projectId}/team/syncOrchestrator POST /api/projects/{projectId}/team/synccommitProjectTeamSync

Both operations require an unbound bearer with api.read and projects.admin, current project Owner authority, an active project with a GitHub App repository selection, and a fresh repository selection code in X-Agentweaver-Team-Sync-Selection. The Gateway forwards the selection code only as a request header. Responses are Cache-Control: no-store.

GET previews changes derived from the current Projects & Config cast and charters. The preview includes configurationRevision, changeSetHash, nothingToSync, and changed .squad/ paths with an added, modified, or removed kind. POST requires expectedConfigurationRevision and expectedChangeSetHash from that preview. The owner recomputes the exact plan and rejects stale project configuration, repository head, or file content with 409 before creating a commit. It writes only .squad/team.md and canonical charter paths for current cast members; it does not load repository files as a team roster or mirror them automatically. The preview hash also binds the selected GitHub installation and numeric repository identity, so a repository rename or replacement requires a new preview even when its path and contents appear unchanged. The optional commit message is limited to 200 characters and cannot contain control characters. These routes are excluded from the MCP tool catalog so repository sync remains an explicit web action.

Repository sync is not AgentSuite export/import. Repository sync reads and commits selected .squad/ files in the configured repository. AgentSuite export/import transfers a digest-checked portable archive, and import stages a casting proposal for review and confirmation. Neither AgentSuite operation reads or writes repository files.

Source: services/gateway/Agentweaver.Gateway/GatewayEndpoints.cs and GatewayRouteCatalog.cs.

MethodPathAuthPurpose
GET/openapi/v1.jsonPublicOpenAPI 3.1 route and schema catalog.
GET/agents/agentweaver.agent.mdPublicOperator agent definition as text/markdown; excluded from OpenAPI and the MCP catalog.
GET/api/v1/authorization/contextBearer; api.read, non-purpose tokenFresh Projects actor, tenant, binding, and effective authority.
GET/health/livePublicProcess liveness.
GET/health/readyPublicGateway host readiness.

The public Gateway surface is an explicit route catalog. The tables below list the routes owned by Projects & Config, Orchestrator, Knowledge, and Events. Unmapped /api/v1/{**path} requests return 404 route_not_found; the Gateway does not provide a generic upstream proxy.

The Gateway preserves owner statuses and response bodies. 202 reports acceptance, not completion. Unavailable or invalid owner responses return 502; owner request timeouts return 504. See Gateway for CORS, body bounds, and selector forwarding.

Identity connection BFF ​

These routes are outside the OpenAPI/MCP catalog. Repo App BFF mappings forward the same path to Identity. They do not establish that the matching Identity producer route is registered in the current host.

Prefix: /api/auth/github/repo-app.

MethodSuffixAuthPurpose
POST/authorizationsBearer; no tenant selectorBegin user Repo App authorization.
GET/authorization/statusBearer; no tenant selectorRead redacted authorization status.
GET/authorizations/{transactionId}Bearer; no tenant selectorRead transaction status.
POST/authorization/refreshBearer; no tenant selectorRefresh user authorization.
DELETE/authorizationBearer; no tenant selectorRevoke user authorization.
MethodFull pathAuthPurpose
GET/auth/github/repo-app/callbackPublic; exact __Host-agentweaver-repo-app-auth transaction cookieForward only code, state, and error to Identity.
GET/auth/github/repo-app/installation/callbackPublic; exact __Host-agentweaver-repo-app-install-auth transaction cookieForward only installation callback fields.

Prefix: /api/connections/copilot-user/v1. Native Identity prefix: /internal/connections/copilot-user.

MethodSuffixAuthPurpose
POST/beginBearer; current connection-scope authorityStart Copilot connection. Optional cliCallbackUri is limited to the fixed IPv4 loopback callback.
POST/completeBearer and exact link cookieComplete state-matched authorization.
POST/refreshBearer; expected revisionRefresh the connection.
POST/revokeBearer; expected revisionRevoke the connection.
GET/{connectionId:guid}Bearer; current connection authorityRead status.
GET/list?scope={project|platform}&scopeId={id}&pageSize={1-50}&afterConnectionId={guid}Bearer; current connection-scope authorityRead a stable page of safe connection receipts for the current issuer, actor, tenant, and scope.
POST/callback-relayPublic; valid pending CLI stateReturn only the protected CLI loopback callback address. It does not return a bearer or GitHub credential.

All authenticated Copilot operations require an unbound bearer and current WriteProjects for project scope, or WritePlatformRuntimeDefaults for platform scope. These permissions require api.read and projects.admin. Existing connections also require the original owner issuer and actor.

The Gateway callback relay accepts a JSON body with state, up to 16 KiB. A larger body returns 413 with request_body_too_large, with or without Content-Length. The Gateway does not forward an oversized body. A query string, a missing media type, or a media type other than application/json returns 400 with copilot_callback_relay_request_invalid. The Gateway forwards the state to the Broker without a bearer and returns the fixed http://127.0.0.1:49173/oauth/callback address only when the protected state is valid and pending. The state expires after five minutes. The completion operation consumes it once and still requires the callback cookie and the original signed-in owner. Web popup callbacks keep their existing opener flow.

Prefix: /api/connections/remote-mcp/v1. Native Identity prefix: /internal/connections/remote-mcp.

MethodSuffixAuthPurpose
POST/registerAdmin; unbound bearerRegister an OAuth binding.
GET/{connectionId:guid}Read; unbound bearer, current owner bindingRead redacted status.
POST/{connectionId:guid}/consentAdmin; unbound bearer, current binding and revisionsPrepare provider consent.
POST/{connectionId:guid}/refreshAdmin; unbound bearer, expected connection/credential/configuration revisionsRefresh owner-held credentials.
POST/callbackAdmin; unbound bearer, pending state-matched bindingComplete code or denied-consent callback.
POST/{connectionId:guid}/disconnectRead; unbound bearer, current owner binding and revisionsClear protected token references.

Copilot and Remote MCP BFF calls forward the optional explicit tenant selector. They are distinct from the direct Broker browser Repo App surface below.

Projects & Config ​

Source: services/projects-config/Agentweaver.Projects.Config/. Native project prefix: /api/projects. Gateway project prefix: /api/v1/projects.

Use Configure providers to set up providers before you accept a run selection. The routes below show where the Gateway exposes project configuration and run-selection operations.

Every response containing a ProjectSummary includes effectiveRoles. Each entry identifies a role name and its exact tenant or project resource scope. Projects & Config includes only active roles for the current caller on the project or its selected tenant and rechecks them against current owner state. Tenant-wide roles appear on each applicable tenant project. These values are for display only: they are not permissions, a client-side authorization cache, or a grant.

MethodNative suffixAuthPurposeGateway
POST/Admin; unbound token, TenantAdminCreate a project and atomically assign the creator active Owner authority with an audit record. Returns 403 for stale or revoked authority and 503 role_assignment_unavailable if database role-write grants are unavailable; failures roll back project creation.Yes, empty suffix
GET/Read; unbound tokenList visible tenant projects.Yes, empty suffix
GET/{projectId}Read; exact signed run when runId is suppliedRead project metadata.Yes
PATCH/{projectId}AdminUpdate name and lifecycle at expectedRevision.Yes
GET/{projectId}/role-assignmentsRead; unbound token, TenantAdmin or project OwnerList active project role assignments.Yes
POST/{projectId}/role-assignmentsAdmin; unbound token, TenantAdminAssign a project role to a tenant member.Yes
DELETE/{projectId}/role-assignments/{assignmentId:guid}Admin; unbound token, TenantAdminRevoke an assignment at expectedRevision.Yes
GET/{projectId}/configurationReadRead current or requested revision.Yes
GET/{projectId}/configuration/choicesReadRead current project-scoped model and platform provider choices. No query parameters; no-store.Yes
PUT/{projectId}/configurationAdminAppend validated configuration.Yes
GET/{projectId}/casting/universesReadList supported universe names for an authorized project.Yes
POST/{projectId}/casting/proposalsAdminStage a complete configuration draft for review.Yes
POST/{projectId}/casting/proposals/scenarioAdminCreate a scenario-based proposal.Yes
POST/{projectId}/casting/proposals/manualAdminCreate a manual proposal.Yes
POST/{projectId}/casting/proposals/blueprintAdminCreate a proposal from a blueprint. Returns the proposal and the skill bindings it couldn't apply.No
GET/{projectId}/casting/proposalsReadList proposals with optional limit (1–100, default 50).Yes
GET/{projectId}/casting/proposals/{proposalId:guid}ReadRead a proposal.Yes
PATCH/{projectId}/casting/proposals/{proposalId:guid}AdminRevise a proposal.Yes
PATCH/{projectId}/casting/proposals/{proposalId:guid}/members/{agentId}/roleAdminChange a member's catalog role and optional display title in a pending draft.Yes
POST/{projectId}/casting/proposals/{proposalId:guid}/confirmAdminConfirm reviewed casting.Yes
POST/{projectId}/casting/proposals/{proposalId:guid}/rejectAdminReject a proposal.Yes
GET/{projectId}/casting/exportAdminExport current casting or optional positive revision.Yes
POST/{projectId}/casting/importAdminStage a digest-checked transfer; request body limit 1 MiB.Yes
GET/{projectId}/agentsuite-exportsAdminExport the current or requested positive configuration revision as a validator-checked AgentSuite package; archive limit 5 MiB.Yes
POST/{projectId}/agentsuite-importsAdminValidate a native AgentSuite archive and stage its agents as a casting proposal; request body limit 24 MiB.Yes
GET/{projectId}/agentsuite-imports/{sourceIdentity}ReadRead a retained AgentSuite import record.Yes
GET/{projectId}/agentsuite-agents/{effectiveAgentId}/policyReadRead the policy bound to an imported agent.Yes
PUT/{projectId}/runs/{runId}/selectionSelectionAccept an immutable run selection.Yes
GET/{projectId}/runs/{runId}/selectionSelectionRead the accepted selection.Yes
PUT/{projectId}/runs/{runId}/interactive-selectionSelectionAccept a new chat run selection from current server configuration. The Orchestrator calls this route during run creation.No
GET/{projectId}/runs/{runId}/cancellation-selectionapi.read, projects.orchestrator, unbound project cancellation authorityRead the saved selection after a fresh Contributor, Owner, or tenant-admin check. Used by Orchestrator cancellation, not run admission.No

Run selection requires a configured platform runtime-defaults revision. On a fresh installation, selection returns 409 platform_runtime_unconfigured until an operator bootstraps a PlatformAdmin and writes the reviewed defaults. See Deploy to Azure.

Project role assignments ​

These routes manage who holds the Owner, Contributor, Viewer, and Orchestrator roles on one project. Gateway operation IDs are listProjectRoleAssignments, assignProjectRole, and revokeProjectRoleAssignment. Every response sets Cache-Control: no-store. None of the routes accept idempotency keys. A repeated assign request returns 409 role_assignment_exists, and a repeated revoke request returns 409 revision_conflict.

Authorization. The request token must be unbound: no project, run, or purpose binding.

  • To list, the caller needs the api.read scope and either the current TenantAdmin role for the tenant or the Owner role on the project.
  • To assign or revoke, the caller needs the api.read and projects.admin scopes and the current TenantAdmin role. A project Owner can't change roles. The service share-locks the caller's membership and checks the exact TenantAdmin assignment and revision in the same serializable transaction as the change. Each change writes an authority_audit row in that transaction.

List. GET /api/v1/projects/{projectId}/role-assignments accepts no query parameters and returns 200 with only active assignments:

json
{
  "projectId": "string",
  "assignments": [
    {
      "assignmentId": "uuid",
      "principalId": "string",
      "role": "owner | contributor | viewer | orchestrator",
      "revision": 1,
      "createdBy": "string",
      "createdAt": "date-time"
    }
  ]
}

principalId is the member's subject under the caller's issuer. createdBy is the subject of the tenant admin who made the assignment. Assignments are sorted by role, then by principalId.

Assign. POST /api/v1/projects/{projectId}/role-assignments accepts a strict JSON body and no query parameters:

json
{ "principalId": "string", "role": "owner | contributor | viewer | orchestrator" }

The principal must have an active membership in the caller's tenant. The route returns 201 with a Location header and this body:

json
{
  "assignmentId": "uuid",
  "projectId": "string",
  "principalId": "string",
  "role": "orchestrator",
  "state": "active",
  "revision": 1,
  "grantedBy": "string",
  "grantedAt": "date-time",
  "revokedBy": null,
  "revokedAt": null
}

Revoke. DELETE /api/v1/projects/{projectId}/role-assignments/{assignmentId}?expectedRevision=N requires one unsigned integer expectedRevision. It returns 200 with the same assignment shape, with state set to revoked and the revision increased by one. The last active Owner of an active project can't be revoked. After the project is archived, a tenant admin can revoke its last Owner.

StatusProblem codeMeaning
400invalid_request, invalid_project_role, invalid_principal_id, invalid_expected_revisionThe query, role, principal ID, or revision isn't valid.
400email_principal_not_supportedEmail is profile data, not a member ID. Sign in and use the member's Broker subject ID.
403forbiddenThe token or current role doesn't allow the operation.
404not_found, principal_not_foundThe project, assignment, or tenant member doesn't exist for the caller.
409role_assignment_exists, project_archived, last_project_owner, revision_conflictThe current state doesn't allow the change.
503role_assignment_unavailableThe runtime database grants for assign and revoke aren't applied. See Runtime authority writes.

NOTE

The web client's existing assignProjectRole and revokeProjectRoleAssignment calls in apps/web/src/api/client.ts send snake_case fields and read a GET /projects/{projectId}/access route that doesn't exist. The web client must use the contract on this page.

Invocation setup ​

POST /api/v1/p1/invocations/{invocationId}/setup is a REST-only Gateway route backed by POST /api/p1/invocations/{invocationId:guid}/setup in Projects. It requires the existing unbound bearer with api.read and projects.admin, plus exactly one X-Agentweaver-Tenant header naming the selected tenant. The Projects owner resolves the actor, membership, and current TenantAdmin assignment from that authenticated request. The route accepts no body or query parameters and returns the immutable Projects setup receipt with Cache-Control: no-store; it accepts no existing project or resource IDs. The Gateway operation ID is createP1InvocationSetup; GET on the same path is readP1InvocationSetup. Both are available through CLI API invocation although neither is exposed through MCP.

The Projects runtime principal can execute only the dedicated issue/read functions for this operation. The issue function creates the project, initial configuration, Owner and Orchestrator assignments, audit events, and setup receipt atomically in the Projects database. Same-invocation retries recheck current authority and the exact readback. This receipt is not authorization or proof for run, Environment, Sandbox, or runtime creation.

GET /api/v1/p1/invocations/{invocationId}/setup forwards to the same Projects path with GET. It requires the same unbound scopes, current TenantAdmin, selected tenant, and empty body/query, and returns only the current validated receipt with Cache-Control: no-store. It exclusively calls the existing read function: an unknown or foreign locator returns 403, stale setup state returns 409, and no read can create projects, assignments, audits, or setup rows. It is REST-only, excluded from MCP, and bounded to 16 KiB like issuance. It proves current state at the owner read, not a cross-service revocation lock or Core invocation provenance.

StatusProblem codeMeaning
400invalid_project_setup_requestThe invocation ID, tenant header, body, or query is invalid.
403forbiddenThe bearer lacks the required scope/current TenantAdmin authority, the selected tenant does not match, or the read locator is unknown or belongs to another actor/tenant.
409project_setup_invocation_conflict, project_setup_receipt_staleThe invocation conflicts with an existing receipt or its current readback is stale.

Setup authority audit ​

GET /api/project-setup-invocations/{invocationId:guid}/authority-audit is also available through the Gateway at GET /api/v1/project-setup-invocations/{invocationId}/authority-audit. It returns only authority-audit events linked to that invocation in the caller's selected tenant. Invocation fixture role events are linked by the exact project name p1-<invocation-id>.

The caller needs an unbound token with api.read and must be a current TenantAdmin or a current Owner of every project represented in the result. An Owner is denied if the invocation has no linked events or includes a project they do not own. The route accepts no query parameters and returns Cache-Control: no-store. It is a REST operation, not an MCP tool.

The response contains at most 32 records. complete is true only when the full result fits in that bound; otherwise complete is false and truncated is true. An incomplete response is not evidence that unreturned events do not exist. Records include event and assignment IDs, event type, resource, role, revision, actor, and timestamp. They never include access tokens or secrets.

json
{
  "invocationId": "uuid",
  "complete": true,
  "truncated": false,
  "records": [
    {
      "eventId": "uuid",
      "eventType": "role_assigned",
      "assignmentId": "uuid",
      "resourceType": "project",
      "resourceId": "project-id",
      "role": "owner",
      "revision": 1,
      "actor": "subject-id",
      "createdAt": "date-time"
    }
  ]
}

Catalog and platform routes ​

MethodNative full pathAuthPurposeGateway full path
GET/api/authorization/contextBearer; api.read, non-purpose tokenRead current authority./api/v1/authorization/context
GET/api/casting/templatesBearerRead built-in casting templates./api/v1/casting/templates
GET/api/catalog/rolesBearerRead built-in roles./api/v1/catalog/roles
GET/api/blueprintsBearer; any signed-in callerList built-in blueprints with their availability.No
POST/api/blueprints/validateBearer; any signed-in callerCheck a blueprint without changing state.No
GET/api/platform/runtime-defaults/api.read, projects.admin, unbound PlatformAdminRead platform runtime defaults./api/v1/platform/runtime-defaults
PUT/api/platform/runtime-defaults/Same PlatformAdmin authorityAppend runtime defaults./api/v1/platform/runtime-defaults
GET/api/platform/componentsapi.read, unbound, current TenantAdmin for the caller's tenant or PlatformAdminRead active platform components and readiness for every area. See Platform components./api/v1/platform/components
GET/api/policies/platform/api.read, active membership, unbound PlatformAdminRead the hash-verified current canonical ACS Policy artifact. Does not require projects.admin./api/v1/policies/platform
POST/api/policies/platform/validateapi.read, active membership, unbound PlatformAdminValidate a complete artifact without changing policy state./api/v1/policies/platform/validate
PUT/api/policies/platform/api.read, projects.admin, active membership, unbound PlatformAdmin with WritePlatformRuntimeDefaultsAppend a validated complete artifact at its expected revision. Off by default: returns 503 unless head writes are enabled. A retry of a saved request returns its receipt./api/v1/policies/platform
POST/internal/projects/{projectId}/runs/{runId}/broker-run-bindingTrusted Broker TLS and current Projects proof checksValidate a Broker run-binding request. Registered only when enabled.No

The Policy API uses the one existing head for the Platform scope and keeps its Policy ID. Only an empty scope gets the server-owned canonical Policy ID. Each artifact contains every policy domain. Reads and writes use the canonical source only; the API does not activate ACS or change the v4 Policy path. See the native ACS contract for request limits, validation outcomes, and write behavior.

Casting through the Gateway ​

Casting routes use Projects & Config as the only configuration authority. The owner enforces ReadProjects for proposal reads and WriteProjects for mutations and export. Writes and export require api.read, projects.admin, and current TenantAdmin or project Owner authority. Catalog reads require authentication. No new roles or idempotency headers are introduced.

MethodGateway pathAuthorizationResult
POST/api/v1/projects/{projectId}/casting/proposals/formulateRun-bound bearer and separate project-writer bearerPending proposal with completed Formulate status.
POST/api/v1/projects/{projectId}/casting/proposals/analyzeRun-bound bearer and separate project-writer bearerPending proposal with completed Analyze status.

Formulate and Analyze are strict Gateway operations with separate request shapes: Formulate requires a goal, while Analyze has no goal and uses read-only repository signals. Both requests include the expected configuration revision, accepted run and root session, idempotency key, canonical prompt, team size, intent, preferred role IDs, and optional universe. They return a pending ProjectCastingProposal with its generation mode and completed status. The generated team remains reviewable; neither operation updates live configuration.

These operations require two bearer credentials. Send the exact run-bound bearer in Authorization and the unbound project-writer bearer in X-Agentweaver-Project-Authorization. Gateway checks that both resolve to the same issuer, actor, and tenant, that the run bearer matches the request's project and run, and that the project bearer has current write authority. Only the run bearer is sent to Orchestrator. Confirm or reject the returned proposal with its current expectedDraftRevision; confirmation also rechecks the base configuration revision.

These operations are browser-only and are excluded from MCP discovery. The separate project-writer bearer is never exposed as an MCP tool argument.

When a native casting request completes, its generation result can include nativeCompletion. This receipt binds the request to its runtime registration, accepted selection, execution fence, native turn, and typed material acknowledgments. An exact retry after verified Host replacement can also include nativeReplay; it identifies the previous and current registrations and proves that the retry produced no new native event. These fields do not replace the public turn-text read route below. SDK cache contents remain private.

Create requests carry expectedConfigurationRevision and either draft, templateId, or roleIds. Scenario and manual requests may also include universe, one of the names returned by the project-scoped universe route; null selects Random (any universe). Patch carries expectedDraftRevision and draft. Confirm and reject carry expectedDraftRevision. Confirmation also checks the proposal's base configuration revision. A stale revision returns 409; rejection does not change configuration. A selected universe stays in the proposal draft and is saved with project configuration only after confirmation. Import accepts expectedConfigurationRevision and transfer and creates a pending proposal, not an applied configuration. Gateway and owner import request bodies are limited to 1,048,576 bytes. Unsupported transfer versions or incompatible teams return 422.

See casting contracts for response fields and Use the Gateway for the review sequence.

Skills ​

Native prefix: /api/projects/{projectId}/skills. Gateway prefix: /api/v1/projects/{projectId}/skills.

MethodNative suffixAuthPurposeGateway
GET/Admin; archived projects allowedRead revision inventory with cursor and pageSize.Yes, empty suffix
POST/importAdminImport validated content with idempotency and digest checks.Yes
PUT/{skillId}/assignmentAdminSave pinned skill assignment at the expected configuration revision.Yes
POST/{skillId}/revisions/{revision:long}/revokeAdminRevoke an imported revision.Yes
MethodNative full pathAuthPurposeGateway full path
POST/api/skills/previewapi.read; unbound requestValidate local skill files without saving./api/v1/skills/preview
POST/api/skills/packageapi.read; unbound requestGroup uploaded files, a ZIP archive, or draft fields into skill candidates without saving./api/v1/skills/package
GET/api/projects/{projectId}/runs/{runId}/agents/{agentId}/skillsSelection; exact agent and accepted pinsRead effective run skills.No

Marketplace sources ​

Native prefix: /api/projects/{projectId}/skill-marketplaces/sources. Gateway prefix: /api/v1/projects/{projectId}/skill-marketplaces/sources.

List, browse, and preview use Read authority. Create, update, remove, and import use Admin authority. Upstream content reads recheck current authority.

MethodNative suffixPurposeGateway
GET/List project sources.Yes, empty suffix
POST/Create a public source.Yes, empty suffix
PUT/{sourceId}Append a source revision.Yes
DELETE/{sourceId}Tombstone using expectedRevision.Yes
GET/{sourceId}/browseBrowse expectedSourceRevision, optional query, page, and pageSize.Yes
POST/{sourceId}/previewValidate selected content at a resolved commit.Yes
POST/{sourceId}/importImport selected content with digest and idempotency checks.Yes

GET /api/projects/{projectId}/skill-marketplaces/definitions uses Read authority and lists the suggested marketplaces. The Gateway path is /api/v1/projects/{projectId}/skill-marketplaces/definitions.

See Projects & Config and Skill marketplace sources.

Orchestrator ​

Caller notifications ​

Native owner prefix: /api/notifications. Gateway prefix: /api/v1/notifications. These routes require an unbound token with current Projects read authority; tokens with project_id or run_id claims return 403 caller_binding_mismatch. See Notifications.

MethodSuffixPurposeGateway
GET?cursor=&pageSize=&projectId=&includeDismissed=Read newest-first pending gates, a total count and an opaque cursor.Yes
POST/{notificationId}/dismissDismiss for the caller without resolving the gate. Bodyless and idempotent.Yes

Responses are no-store. Token bindings do not narrow this caller-wide endpoint; use projectId. The default excludes caller dismissals; shared Flow reads use includeDismissed=true. Unknown or repeated query parameters return 400 query_invalid.

Source: services/orchestrator/Agentweaver.Orchestrator/.

Runs ​

Native prefix: /api/projects/{projectId}/runs. Gateway prefix: /api/v1/projects/{projectId}/runs.

These routes start a new chat run, deliver its first message, and cancel it. Create and start require the project Orchestrator role (acceptRunSelection). Owner or Contributor alone receives 403 when creating a chat. A tenant admin grants the caller the project Orchestrator role through /api/v1/projects/{projectId}/role-assignments.

MethodSuffixTokenPurposeGateway
POST/Not bound to a runSave the first message, mint runId and rootSessionId, and accept the run selection. Returns 201 with awaiting_binding.Yes
POST/{runId}/startBound to the runAccept the root session and deliver the saved first message once. Returns 200 with started and the current runtimeStartup summary when startup is enabled.Yes
POST/{runId}/cancelNot bound to a runCancel any run as a current project Contributor, Owner, or tenant admin. Viewer receives 403. Returns 200, including terminal no-ops; cleanup queue saturation can return 503 runtime_start_queue_full after cancellation is saved.Yes
POST/{runId}/messagesBound to the runSend user text to the coordinator or an explicitly selected active session. Returns an Events admission receipt.Yes

Create, cancel, and run messages require exactly one Idempotency-Key header. A retry with the same key and body returns the original result. A retry with the same key and a different body returns 409 idempotency_conflict. Start takes no body and no key; a repeated start returns the same result without sending the first message again. Cancel on a finished run returns 200 with alreadyTerminal: true and does not change state. Cancellation receipts are scoped to each caller. Cancellation is saved before the service queues runtime cleanup. If that queue is full, the service returns 503 runtime_start_queue_full and keeps the cancellation. Retry with the same key and body to queue cleanup. Start has a 30-second deadline covering its request lock and downstream calls; a timeout returns 504 run_start_timeout. Start after cancellation returns 409 run_terminal.

Runtime startup continues in the background after root admission. Its summary reports pending, ready, or blocked; pending does not mean AgentHost is ready. Session status can also report cleanup_pending or cleanup_complete after cancellation. A retry with fresh run authority can resume pending startup without sending the first message again. When a start replay checks a ready result, Orchestrator reads the current Environment placement and authenticated Host GET /runtime/v1/readiness. An unavailable or not-ready Host keeps the result pending; stale Host or placement evidence makes it blocked. This read does not activate the Host or provision a Sandbox.

The create request body has firstMessage (1–32,768 UTF-8 bytes), expectedProjectConfigRevision, and optional title, workflowId and p1SetupInvocationId. The latter is only an existing Projects setup receipt locator, not a caller-supplied receipt, hash, run ID or Core invocation ID. The Gateway accepts create bodies up to 256 KiB. Responses never include the first message.

When an invocation locator is present, Core saves the locator with the pending request. Create does not read the public Projects receipt. Projects selection is created after the request commits; selection failure leaves a resumable request, not an accepted invocation.

At bound start, Core checks current Projects selection and authority and calls the narrow internal Projects verifier with the exact run-bound bearer. The verifier requires current TenantAdmin authority for the receipt's setup actor. Core then locks the saved request and, in one transaction, saves the full verified receipt and its versioned deterministic hash, accepts the root, creates the initial decision, and writes the immutable invocation binding. Events registration and first-message delivery remain outside that transaction and are retryable. If verification fails before the first root is accepted, the request stays pending and that attempt creates no root, decision, binding or first-message delivery. A later delivery retry reuses any root and binding already committed. If the journey cannot continue, cancel the owned run through the existing cleanup path. Projects locks do not span the Core commit: revocation after the remote check can race with that commit. There is no distributed-lock or current-at-commit revocation guarantee.

Current invocation binding ​

Native internal path: GET /internal/projects/{projectId}/runs/{runId}/p1-invocation-binding. There is no public Gateway or MCP route for this owner-to-owner read. The caller must be the accepted actor with an exact run-bound token and current api.read and projects.orchestrator authority. The request accepts no query or body and returns Cache-Control: no-store.

The version 1 P1InvocationBinding response contains contractVersion, coreInvocationId, setupInvocationId, setupReceiptHash, tenantId, projectId, runId, rootSessionId, actorIssuer, actorSubject, membershipId, membershipRevision, acceptedSelectionHash, executionFence, rootStateVersion, and acceptedAt. IDs and acceptance evidence come from Core's immutable binding, not caller JSON. The receipt hash uses SHA-256 over UTF-8 bytes of the versioned prefix agentweaver.p1.setup-receipt.v1\n and the complete typed receipt serialized with camel-case property names, including nullable Owner fields. The saved provenance records hash version 1.

The read joins the actual accepted run and active root session, compares the current execution fence and selection hash, and checks fresh Projects selection and actor authority. A missing binding returns 404; stale evidence returns 409. Historical acceptance is not current authority, and an existing root without a binding cannot be enrolled afterward. Environment's separate invocation-bound creation path consumes this read before its own creation effects and retains operation/result links in Environment owner transactions. The Core response alone is not a provider-resource receipt or a Host/native observation join. The separate Environment creation-evidence contract documents Environment's authenticated retained-record read and Host's invocation-specific GET /runtime/v1/readiness/p1-evidence consumer.

Run messages ​

Native path: POST /api/projects/{projectId}/runs/{runId}/messages. Gateway path: POST /api/v1/projects/{projectId}/runs/{runId}/messages.

The request body has text (1–32,768 UTF-8 bytes) and optional targetSessionId. With no target, the message goes to the run's coordinator session. An explicit target must be an active session in the same run. The Gateway accepts bodies up to 256 KiB.

The caller needs api.read, projects.orchestrator, an owner-audience token bound to the exact project and run, and fresh Projects authority for the accepted run selection. The issuer and subject in the receipt come from that authenticated token; caller-supplied sender identities are rejected. An unbound token or a token bound to another project or run receives 403.

The 200 receipt includes the Orchestrator message ID, the Events journal message and thread IDs, thread sequence, target session, and authenticated sender identity. A retry with the same key and body returns the same receipt without adding a second journal message. Reusing a key with different text returns 409 idempotency_conflict. The key reserved for first-message delivery ({runId}:first) cannot be used for a follow-up message.

Run list ​

Native path: /api/projects/{projectId}/runs. Gateway path: /api/v1/projects/{projectId}/runs.

MethodQueryAuthPurposeGateway
GETstate, startedBy, cursor, pageSizeReadList accepted runs, newest first.Yes, listProjectRuns

The caller needs the api.read scope and project or tenant read permission. A run-bound token sees only its own run. pageSize defaults to 25 and accepts 1–100. state takes a comma-separated list of idle, active, blocked, completed, failed, indeterminate, and cancelled, or the open and terminal aliases. startedBy=me filters to runs accepted by the caller's exact issuer and subject. The Sessions page uses this filter. Unknown or repeated query parameters return 400 query_invalid. A bad filter, cursor, or page size returns 400 run_state_filter_invalid, run_started_by_filter_invalid, cursor_invalid, or page_size_invalid. Pass nextCursor back with the same filters and page size; the cursor is also bound to the caller identity when startedBy=me is set. Each item includes the selected workflowId and needsInputCount, the count of durable pending decision gates. Saved run requests supply title and goal; they can be null for older or non-interactive runs without a saved request.

Project run session history ​

MethodNative pathAuthPurposeGateway path
GET/api/projects/{projectId}/runs/{runId}/history/sessionsReadRead a run's session tree./api/v1/projects/{projectId}/runs/{runId}/history/sessions

This read uses fresh project authority, so an authorized project reader does not need to be the actor who accepted the run. A run-bound token remains limited to its bound run. The Gateway route returns Cache-Control: no-store.

Project issue and pull request lists ​

These reads return Agentweaver's stored data. They make no source control provider call at read time, so they don't need a provider credential.

PathQueryGateway
GET /api/projects/{projectId}/source-control/issuesstate, cursor, pageSizeYes, listProjectIssues
GET /api/projects/{projectId}/source-control/pull-requestsstate, cursor, pageSizeYes, listProjectPullRequests

The Gateway path adds /v1 after /api. Both routes need the api.read scope, return Cache-Control: no-store, and recheck Projects read permission after the read. If permission is lost during the read, the route returns 403 with no items. pageSize defaults to 25 and accepts 1–100. Unknown or repeated query parameters return 400 query_invalid. A bad cursor or page size returns 400 cursor_invalid or page_size_invalid. Pass nextCursor back with the same filter and page size.

Issue list. Returns repository issues that periodic issue sync linked to backlog tasks, ordered by issue number, newest first. The caller needs current project or tenant readProjects permission. Run-bound tokens are rejected. state is open (default), closed, or all; another value returns 400 issue_state_filter_invalid. Archived tasks and tasks without an issue link aren't listed, and a project without an issue sync configuration returns an empty page. Each item has the task ID and backlog state, provider, repository, issue number, stored title, stored state, and task timestamps. The backlog doesn't store an issue URL or author, so items don't include them.

Pull request list. Returns pull requests that the project's runs created or reused, as Source Control recorded them, ordered by recordedAt, newest first. The caller needs the same permission as the run list. A run-bound token sees only its own run's records. state is open (default), closed, merged, or all; another value returns 400 pull_request_state_filter_invalid. Each item has the provider, repository, number, title, URL, state, head and base branch and commit, and its provenance: runId, disposition (created or reused), recordedAt, and updatedAt. Title and state are the values from the last time a run recorded the pull request, not live provider values.

The pull request list isn't a complete pull request history. Recording starts when Orchestrator migration 032_source_control_pull_request_records.sql is applied. coverage.recordedSince reports that time, and coverage.includesEarlierPullRequests is always false. Older pull requests aren't recorded. Until migration 032 is applied, the route returns 503 pull_request_records_unavailable, not an empty list. An empty list would wrongly tell a client that the project has no pull requests; the 503 says the records don't exist yet. Migration 032 is code-only: startup, the default migrator, and the PostgreSQL initializer don't apply it.

These routes are the data source for the Priority issue and pull request pickers. When pull request recording has not started, the picker explains that records are unavailable rather than treating the response as an empty list.

Project metrics and usage ​

Use these read-only routes for one project's dashboard:

Gateway path (GET)Owner pathOperation ID
/api/v1/projects/{projectId}/metrics?from=&to=&bucket=dayOrchestrator /api/projects/{projectId}/metricsreadProjectMetrics
/api/v1/projects/{projectId}/usage?from=&to=Events & Sessions /api/projects/{projectId}/usagereadProjectUsage

Both owners require api.read, their own audience and the Projects audience, and a fresh Projects authorization context. The caller needs project readProjects or readRunSelection, or tenant readProjects. Unbound and project-bound callers can read the project. A run-bound caller sees only its own run. Both responses use Cache-Control: no-store.

from is inclusive and to is exclusive. Supply ISO dates (2026-10-01) or timestamps with an explicit offset (2026-10-01T00:00:00Z). Dates start at UTC midnight. When to is omitted, it defaults to the current UTC time. When from is omitted, it defaults to 30 days before to. An interval can span at most 92 days. Equal bounds are valid and return no interval activity. Only metrics accepts bucket; its only value is day. Unknown or repeated query parameters, invalid dates, reversed bounds, and unsupported buckets return a 400 problem response with title and code set to query_invalid. The response does not include exception text. A default start date earlier than the supported date range is also invalid.

Metrics returns projectId, normalized from and to, the counts below, and series. Current state and lifetime counts are not limited by the date range. They still respect tenant, project, and run-bound scope.

Fieldv1 definition0.x dashboard mapping
activeRunsRuns whose derived state is active, including presenting root turns.Active runs tile; does not include the separate active-agent count.
blockedRunsRuns whose derived state is blocked.Additional state detail, not a summary tile in 0.x.
runsInRangeRuns with created_at in [from,to).Runs this week when callers select that week; Created total for the selected range.
runsTotalAll accepted runs in the authorized scope.Total run count.
sessionHistoryRecordsTotalThe all-date count of records currently returned by each selected accepted run's root-scoped session-history tree. Archived records retained in the tree count; detached subtrees leave their former root projection. null means at least one selected accepted run has no root or an empty tree; an authorized scope with no accepted runs returns 0.A session-history summary, not a run count or literal 0.x handoff total.
completedRunsTerminal runs (completed, failed, cancelled, indeterminate) with completed_at in [from,to).Completed total and Done series; not the 0.x completed-task count.
succeededRunsRuns in completedRuns whose derived state is completed.Numerator for run success; not the 0.x agent-dependency success measure.
series[].dateUTC calendar date, ascending, for each day intersecting the interval.Runs over time and daily activity.
series[].createdRuns created within the interval on that UTC day.Created series.
series[].completedTerminal runs completed within the interval on that UTC day.Done series.

Days with no activity have zero counts. An equal-bound interval has an empty series. A run created before the interval can contribute to its completion count. Terminal rows without completed_at do not contribute to completion metrics.

sessionHistoryRecordsTotal ignores the selected date range. It counts only records in accepted project-run trees under the current tenant, project, and optional exact run-bound authority; unrelated coordination rows and private Chief of Staff conversations are excluded. The count shares the metrics owner's single database snapshot and is null, not a partial total, when any selected accepted run's native history tree is unavailable.

These definitions map to the 0.x dashboard controls. The current implementation uses persisted owner data, not Application Insights, and cannot reproduce historic 0.x telemetry. Run success is succeededRuns / completedRuns; display it as unknown when the denominator is zero. 0.x used per-agent dependency success, so the two percentages are not equivalent.

Usage returns projectId, normalized from and to, usageByModel, and usageByAgent. Each array item has id (persisted model_id or agent_id), requestCount, inputTokens, outputTokens, cachedTokens, cacheWriteTokens, reasoningTokens, avgDurationMs, runs, cost, and unpricedRequestCount. Empty intervals or projects have empty usage arrays. runs counts distinct run_id values represented in that group and interval. These groups replace the model metrics and usage portion of the agent leaderboard, not agent-role or agent-success telemetry.

Token and request counts are sums of recorded measurements. avgDurationMs is the arithmetic mean of ledger-event durations, not a request-weighted mean. If any included row lacks a measurement, that aggregate is null, not zero. TTFT is not returned because the ledger does not record it.

cost[] keeps a separate subtotal for each (priceUnit, disposition) pair. Disposition is estimate, reconciled, or unpriced. Never sum across units. An unpriced amount remains null, including a missing unit. unpricedRequestCount sums request counts on unpriced rows; it is null when any such row has an unknown request count, and zero when no rows are unpriced. Reads do not price, reprice, reserve, or change budgets.

Cross-project overview is out of scope. The Gateway proxies each owner; it does not combine metrics and usage into one response. Clients that need aligned intervals should pass the same explicit bounds to both routes.

Chief of Staff ​

Native prefix: /api/chief-of-staff. Gateway prefix: /api/v1/chief-of-staff.

These routes store a caller's private Chief of Staff conversations and Priorities. They never start, cancel, or change runs, sessions, or gates. New chats use the Runs routes, and the conversation entry binds the returned run. For guidance, see Chief of Staff.

MethodSuffixQueryPurposeGateway
GET/conversationscursor, pageSizeList my conversations, newest first.listChiefOfStaffConversations
POST/conversations—Bind a run that I created to a conversation entry. Returns 200 with the same entry on repeat.bindChiefOfStaffConversation
GET/conversations/{conversationId}—Read one of my conversations.getChiefOfStaffConversation
GET/priorities—List my Priorities in order, with orderRevision.listChiefOfStaffPriorities
POST/priorities—Create a Priority at the end of the list. Requires Idempotency-Key. Returns 201, or 200 on replay.createChiefOfStaffPriority
PUT/priorities/order—Replace the order at expectedOrderRevision.reorderChiefOfStaffPriorities
GET/priorities/{priorityId}—Read one Priority.getChiefOfStaffPriority
PATCH/priorities/{priorityId}—Change outcome, notes, state, or checklist at expectedRevision.updateChiefOfStaffPriority
POST/priorities/{priorityId}/links—Add a typed link at expectedRevision.addChiefOfStaffPriorityLink
DELETE/priorities/{priorityId}/links/{linkId}expectedRevision (required)Remove a link.removeChiefOfStaffPriorityLink

Every route requires the api.read scope and a token that isn't bound to a project or run. A bound token returns 403. The Orchestrator reads fresh Projects authority on each call and returns only the caller's rows; another user's conversation or Priority returns 404.

Access rules:

  • Binding a conversation requires read permission on the project and a run that the caller created through POST /api/v1/projects/{projectId}/runs. Another user's run returns 404 conversation_run_not_found.
  • Adding a link requires read permission on the linked project. A conversation link must name one of the caller's conversations in the same project.
  • Removing a link doesn't require project access, so users can remove links to projects they no longer read.
  • When the caller loses read permission on a project, conversations and links in that project return access: unavailable with only their identifier, kind, and creation time. Priority outcome, notes, and checklist are the caller's own content and stay visible.

Revisions and conflicts:

  • Each Priority has a revision. Writes with a stale expectedRevision return 409 priority_revision_conflict. Reread the Priority, then retry.
  • The list has an orderRevision. A stale reorder returns 409 priority_order_conflict. A reorder that doesn't name every Priority exactly once returns 400 priority_order_invalid.
  • A create replay with the same key and body returns the original Priority. A changed body returns 409 idempotency_conflict.
  • Limits: 100 Priorities (409 priority_limit_reached), 50 links per Priority (409 priority_link_limit_reached), and 50 checklist items. A duplicate link returns 409 priority_link_exists.

Link kinds are run, conversation, issue, pull_request, and artifact. Every link names projectId. run needs runId, conversation needs conversationId, issue and pull_request need number, providerId, and repository: { owner, name }, and artifact needs runId and artifactId. Identity is returned unchanged in list, read and write receipts, and removed with other protected target fields after read loss. New repository links without complete identity return 400 priority_link_invalid. Before Core migration 033, a compatible owner returns 503 database_update_pending for those saves and leaves the revision unchanged. Existing number-only rows remain readable; clients must refuse ambiguous targets rather than infer a repository from the number.

Reads resolve each link:

Kindstate
runThe current run state from the run list, or access: missing when the run doesn't exist.
conversationThe run state, or the request state (awaiting_binding, cancelled) before the run starts.
issue, pull_request, artifactunavailable. The owners have no current-state read for these items.

Priority state is active, achieved, or dropped. It's the user's own judgment and doesn't depend on run state, so an outcome survives runs ending. An empty notes value clears the notes, and checklist replaces the whole list.

Coordination ​

Native prefix: /api/projects/{projectId}/runs/{runId}/coordination. Gateway prefix: /api/v1/projects/{projectId}/runs/{runId}/coordination.

All routes use Coordination authority, then validate operation-specific decision versions, execution fences, session relations, and receipts. Registering or accepting owner state does not start an automatic scheduler.

MethodSuffixPurposeGateway
POST/rootAccept root owner state.Yes
GET/statusRead owner run status.Yes
POST/recoveryRecover owner execution state.Yes
POST/sessions/{sessionId}/runtime-replacementsReplace the coordinator root Host using a completed native-turn receipt.Yes
GET/sessions/{sessionId}/runtime-replacements/{operationId}Read the saved Host-replacement operation.Yes
POST/sessions/{sessionId}/decisions/outcomePropose an outcome decision.Yes
POST/sessions/{sessionId}/actions/propose_outcome_specPropose outcome specification.Yes
POST/sessions/{sessionId}/actions/select_workflowSelect workflow.Yes
POST/sessions/{sessionId}/actions/propose_work_planPropose work plan.Yes
POST/sessions/{sessionId}/actions/revise_work_planRevise work plan.Yes
POST/sessions/{sessionId}/actions/dispatchDispatch an accepted MAF checkpoint through configured owner integrations.No
POST/sessions/{sessionId}/actions/request_assemblyRequest assembly.Yes
GET/sessions/{sessionId}/decisionsRead current decision state.Yes
GET/sessions/{sessionId}/treeRead session tree.Yes
GET/sessions/{sessionId}/statusRead activity, lifecycle, and blockers.Yes
GET/sessions/{sessionId}/runtime-observation/v1Read current runtime evidence; native registration is conditional.Yes
GET/sessions/{sessionId}/runtime-observation/v2Read paged runtime evidence with an exact-attempt lookup.Yes
POST/sessions/{sessionId}/turn-failureReport failed turn.Yes
POST/sessions/{sessionId}/decisions/gates/{requestId}/answerAnswer exact pending question.Yes
POST/sessions/{sessionId}/decisions/questionsRequest a question gate.Yes
POST/sessions/{sessionId}/decisions/outcome/questions/nextRequest the next outcome question.Yes
POST/sessions/{sessionId}/decisions/approvalsRequest approval.Yes
POST/sessions/{sessionId}/decisions/gates/{requestId}/acknowledgeAcknowledge gate.Yes
POST/sessions/{sessionId}/decisions/gates/{requestId}/approveApprove exact gate.Yes
POST/sessions/{sessionId}/decisions/gates/{requestId}/rejectReject exact gate.Yes
POST/sessions/{parentSessionId}/childrenRegister child owner state.Yes
POST/sessions/{parentSessionId}/spawnAccept a spawn request.Yes
POST/sessions/{sessionId}/forkAdmit an explicit-event fork.Yes
POST/sessions/{sessionId}/detachDetach eligible child.Yes
POST/sessions/{parentSessionId}/children/{childSessionId}/archiveArchive eligible completed child.Yes
POST/sessions/{sessionId}/idle-subscriptionsAccept idle subscription.Yes
POST/sessions/{sessionId}/steeringRecord steering.Yes
POST/sessions/{sessionId}/messagesAccept addressed message.Yes
POST/sessions/{sessionId}/turn-boundaryAdvance turn boundary.Yes
POST/sessions/{sessionId}/turn-completionRecord turn completion.Yes
GET/sessions/{sessionId}/notificationsRead owner notifications.Yes
POST/sessions/{sessionId}/notifications/{notificationId:guid}/acknowledgeAcknowledge notification.Yes
POST/sessions/{sessionId}/messages/{messageId:guid}/acknowledgeAcknowledge message.Yes
GET/policy-evaluations/{receiptId:guid}Read immutable policy receipt.Yes
GET/policy-evaluations/{receiptId:guid}/admissionRecheck policy receipt admission.Yes
GET/sessions/{sessionId}/build-test/commands/{checkpointId}/{stepId}Read accepted BuildTest command.No
GET/sessions/{sessionId}/build-test/commands/{checkpointId}/{stepId}/workspace-seedRead pinned repository seed.No
POST/sessions/{sessionId}/build-test/commands/{checkpointId}/{stepId}/workspace-capture/verifyVerify produced Workspace capture.No
POST/sessions/{sessionId}/suspendRequest fenced suspend.No
POST/sessions/{sessionId}/resumeRequest retained-Workspace resume.No

GET /api/v1/projects/{projectId}/runs/{runId}/coordination/sessions/{sessionId}/runtime-observation/v2 requires current Coordination authority and rechecks the accepted selection, owner state, decision, session mapping, and execution fence before it returns. The response uses Cache-Control: no-store. pageSize accepts 1 through 100 and defaults to 100. A returned cursor pins later pages to the same snapshot and expires after 24 hours. Use attemptId for an exact lookup; it must be a non-empty GUID and cannot be combined with cursor.

An exact lookup returns at most 100 facts. If more facts exist, the response sets exactUnavailableReason to attempt_history_exceeds_bounded_aggregate and returns a history cursor. Use that cursor without attemptId to browse the retained history. If the owner has no exact evidence, it returns attempt_evidence_not_retained; an empty result does not prove that the attempt did not occur.

The history reports whether v2 evidence coverage started. A missing coverage marker reports complete: false and incompleteReason: "legacy_or_uninstrumented_history". Missing native-send, tool-execution, or consumption proof remains unavailable; an empty result or an owner reservation does not prove that native work ran. A ToolPermissionRejected fact means the runtime recorded a rejection decision for an exact tool-call limit denial. It does not confirm SDK delivery or tool execution. Version 1 remains unchanged. See runtime observation contracts for the response fields and evidence limits.

POST /api/v1/projects/{projectId}/runs/{runId}/coordination/sessions/{sessionId}/runtime-replacements requires the current coordinator-root authority and a RuntimeReplacementRequest with contractVersion, a stable operationId, and the expected runtime instance, registration revision, execution fence, and accepted-selection hash. The owner checks those values against current state before it replaces the Host. Reuse the same operation ID and body to retry an uncertain request.

The response and matching GET route return a RuntimeReplacementSummary. pending and cleanup_pending are not completion. Read the same operation until it reaches a terminal state; do not start a second replacement while the first operation is unresolved. A ready summary includes the old and new runtime registrations, Pod identities, retained workspace generations, cache receipt, and reconstruction evidence. See runtime contracts for the receipt rules.

Active coordinator sessions also receive executionRecovery, a read-only view of the latest bound MAF checkpoint. A failed or indeterminate run still receives this projection when its session lifecycle remains active. The response reports checkpoint status and dependency readiness, pending child dispatches, BuildTest, OpenPullRequest, Merge, IndependentReview, and RubberDuck intent/receipt evidence, failed dependencies, and the current pending decision blocker. RubberDuck operations also expose failureCode for a retryable owner failure or invalid verdict. External-effect intents without receipts are marked mayRepeat; unresolved running effects are indeterminate. At a recovered child join, the one supported committed OpenPullRequest effect is reported as reconcileCommitted until its original intent receives a saved receipt. This state means recovery must read and verify the already stored pull request; it does not mean the effect can be repeated or is complete. A saved terminal receipt is reported only as recorded evidence, not as proof of physical exactly-once execution. Missing or plan-mismatched checkpoints, or checkpoint progress incompatible with the accepted plan, are marked unavailable, not safe or complete. The projection does not dispatch work or reconcile children.

For a non-active coordinator session, the status response reports persisted owner state and returns blockers: []. It omits executionRecovery and does not read decisions or checkpoints. A cancelled lifecycle does not imply idle activity, completed effects, or successful physical cleanup.

Recover a Host at a pending gate ​

POST /recovery keeps its existing owner-state-only behavior when the request omits checkpointRecovery. That path requires a recorded failed or indeterminate state and failure cause and reference. The opt-in object can recover an idle, active, blocked, failed, or indeterminate run. It pins the source checkpoint, decision version, current root runtime registration, and accepted selection.

The opt-in path supports two boundaries:

  • Pending gate. The owner accepts this path only when the exact gate is still pending for the authorized actor and the checkpoint has no pending child dispatch, child association, or platform-effect intent. It uses the Host continuation described below.
  • Saved child join. A child join is the saved association between a work-plan item and its child session. The owner checks the saved child boundary and records a frozen child manifest. It also advances the fence and writes a checkpoint with recovery lineage. The owner continues each saved, nonterminal child that has no unresolved native send. It keeps each child session, association, startup intent, and saved dispatch message. The root and every required child must have a current registration before any Host bootstrap starts. The owner keeps dispatchHeld set until the root and all required children pass readiness checks. The only supported platform-effect exception is one running OpenPullRequest intent with no receipt and an exact committed Source Control operation and stored result. The owner checks this before it advances the fence. Missing, pending, uncertain, or mismatched operation evidence blocks recovery. A 202 response means that the owner saved the admission or has more continuation work. It does not mean that the child task has completed.

The owner rejects other boundaries and unsupported platform-effect history. Both paths require matching fences and versions, current authority, and the existing runtime, checkpoint, native-work, and terminal-cleanup checks. A recovery request does not establish that the old Host is unhealthy.

For a pending gate, the owner advances the fence once. It keeps the same gate request and choices; it does not answer, cancel, or recreate the gate. The Environment owner retires the old placement and creates the replacement. Orchestrator then creates a next-fence registration and requires authenticated Host readiness from the native cache or journal rebuild path. A fresh Host session is not ready.

An accepted gate continuation returns 202 with checkpointRecovery.phase set to pending. Retry the same request with the same idempotency key after a transport or timeout failure to continue the saved step. A ready or blocked result returns 200. ready means the Host restored the saved boundary. It leaves the gate pending and the run incomplete. A later gate answer uses the same request ID at the current fence and decision version.

If Host activation fails after the Broker saves the bootstrap receipt with runtime_delivery_unavailable, runtime_receiver_unavailable, runtime_source_credential_unavailable, runtime_configuration_conflict, or runtime_operation_conflict, the operation becomes blocked with reason checkpoint_recovery_host_bootstrap_spent. Do not retry that blocked operation: the bootstrap credential cannot be replayed. Start a new POST /recovery operation with a new idempotency key and the failed runtime ID and registration revision. The owner advances the fence once, retires the failed Host, and uses new operation IDs. It does not resend the credential or roll back authority.

For a saved child join, guarded owner writes return 409 with checkpoint_recovery_dispatch_held while the hold is active. The continuation does not send another child task message. In its final owner transaction, it imports a completed-but-unjoined result only after it verifies the saved result material, child session and fence, and native accounting against the frozen manifest. A missing, malformed, or mismatched result keeps the hold active. The replacement Host must restore a compatible native cache or saved turn history before it can report readiness. Configuration-only, zero-turn child state is not supported by this recovery path and keeps the hold active. After recovery is ready, ordinary dispatch can send the saved message for a member that was pending and unsent. Retry a pending request with the same idempotency key. A new key does not bypass an active hold.

If a child-join recovery becomes blocked at Host activation after the replacement registrations are ready, you can start a new recovery operation with a new idempotency key. The new request must use the blocked operation's recovery checkpoint as its source. The owner accepts this retry only when the child manifest still binds the same plan, messages, prompts, and results; it has complete retirement and replacement-registration evidence; and every pending dispatch has owner evidence that it was not sent. That evidence can be an absent native row or the same locked native origin from the frozen manifest, still prepared at owner revision 1 with no report or accounting progress. The owner also verifies the prior effective binding. A prepared origin is eligible only when the full no-send proof passes; other native states remain unsupported. The owner returns 409 checkpoint_recovery_dispatch_held while the earlier recovery is still pending. It returns 409 checkpoint_recovery_supersession_unavailable when it cannot prove the supersession conditions.

The new operation advances the fence again, writes its own checkpoint and dispatch hold, and restores the root and required children again. It does not make the blocked operation ready or reuse its bootstrap. The blocked operation stays blocked. Its replay reports supersededByOperationId; its dispatchHeld field reflects the run's current hold. The blocked operation cannot change or release the successor's hold. The run's latest status reports the new operation and its active hold. Only the new operation can release that hold after readiness and result checks pass. For a prepared native origin, the final ready transaction appends one verified native-child-rebind receipt before it releases the hold. It does not change the original dispatch row. ready still means that the Host restored the saved boundary; it does not mean that a child task or the run is complete. After release, ordinary dispatch uses the same saved child, association, message, and prompt through the effective binding. Unsupported or unresolved child history stays held for review.

For gate recovery, readRunStatus and root readSessionStatus expose the current recovery step, reason, checkpoint IDs, fences, and old and new runtime identities. For child-join admission, the status exposes boundaryKind, dispatchHeld, childManifestSha256, and any supersession link. replayRunEvents exposes committed recovery progress through its cursor. These reads do not retry the operation. For gate recovery, do not start a second recovery with a new key while the first operation is pending. A new key is allowed after gate recovery is blocked. A child-join hold remains active until all required registrations and readiness checks are complete. The final owner transaction joins verified completed-but-unjoined results before it releases the hold.

Dispatch completion and startup readback ​

POST /sessions/{sessionId}/actions/dispatch returns the current checkpoint projection. If childRuntimeStartup reports pending, retry the same dispatch request with the same decision version and WorkPlan ID. Dispatch does not wait for a child-start worker that holds the startup lease.

If the first response is lost after the child result is saved and an independent-review gate is pending, retry the same request to read the saved result and receipt. The retry does not send the child turn again.

completionEvidence contains at most 512 verified child-turn receipts retained by the checkpoint. Each receipt binds request, prompt, and output hashes to the WorkPlan, association, logical child session, native SDK session ID, runtime registration, accepted selection, execution fence, source, image, model selection, actual model, native completion and usage event IDs, and the acknowledged user and assistant material. The logical child session comes from the runtime registration; the SDK session ID comes from the native request context. The receipt returns material references, positions, and hashes, not prompt or output text. For an open WorkPlan item, it also returns the hash of the full dispatched item. The owner compares this hash with the current confirmed item before it derives task completion.

taskCompletion is present only when the Orchestrator joins a unique task claim on the root to the confirmed one-item WorkPlan, completed checkpoint, child receipt, and output witness. It is an owner-derived projection; clients cannot set a task to done. A pending startup, incomplete checkpoint, missing or stale receipt, or failed evidence join does not produce task-completion evidence. Unpriced usage may remain in the usage ledger but does not prove task success.

When a ready runtime summary is read, the owner rechecks readiness and projects the current registration, selection, model source, image digest and platform, and Pod UID. This readback does not require P1 setup provenance. P1 invocation IDs remain optional and do not replace runtime evidence.

For IndependentReview, platformGateOperations carries approvalRequestId, evidenceHash, and reviewDecision (null while pending). Its effect recovery state is awaitingApproval until an answer is checkpointed. When dependency results are ready, dispatch records the immutable review intent before opening one coordinator Approval decision. Its prompt identifies the reviewed source, workspace/build-test receipt, or pull request head. The accountable actor answers the existing /decisions/gates/{requestId}/answer route with approve or reject (also used when requesting changes). A matching approval releases the gate only after its terminal receipt is saved. Rejection saves a failed gate and leaves dependents blocked. An unrelated decision, changed workspace or provider pull request head, or revoked run authority cannot complete the gate. Each IndependentReview step must have a dependency path from every declared BuildTest step. Each Merge step must have a dependency path from every IndependentReview and RubberDuck step. Content-only workflows may omit BuildTest.

For RubberDuck, dispatch requires the current coordinator-root AgentHost registration and action-grant owner; otherwise the platform gate is unavailable and is not replaced by ordinary model work. The checkpoint stores the operation and a digest of the accepted workflow revision, actor, fence, selection, and exact recorded ancestor results and receipts before the owner call. The owner receives only that bounded evidence in a read-only turn. The same operation ID is used for retries. A fully recorded owner response can be replayed after a host restart; a partial turn is not sent again and cannot complete the gate. reviewDecision records passed, requestChanges, or failed. Only passed releases dependent steps. A request for changes or invalid verdict records a failed gate; stale bindings and unavailable owner calls leave the gate incomplete. The recovery operation's failureCode identifies the recorded owner failure or invalid response.

The dispatch body may include openPullRequestWorkspaces, an object keyed by OpenPullRequest step ID. Each value contains workspaceId, workspaceIncarnationId, baseSha, branchName, headSha, and baseBranch. The Source Control owner checks the current repository pin and exact workspace revision before it creates or reuses a pull request. The Orchestrator stores the request and operation identity before the owner call and reuses both after a retry or recovery. The owner records that operation before contacting the provider. Recovery reuses only the matching pull request, including when it has closed; it never creates another pull request for the same operation. A missing or ambiguous provider result fails closed. A gate succeeds only after the owner returns a valid pull request number, URL, and matching head SHA and the Orchestrator saves its receipt. The owner holds a workspace revision lease while checking the workspace and writing to the provider. An owner error or a changed decision, source binding, or workspace leaves the gate incomplete, so dependent steps do not run. This executor requires the private Orchestrator:SourceControlOwner:OwnerBaseAddress configuration.

For each Merge step, dispatch may include a mergeInputs entry keyed by step ID. Each entry contains method and may contain pullRequestNumber with expectedHeadSha; the number and head must be supplied together. When there is exactly one completed OpenPullRequest ancestor, the dispatcher can derive that pair and the caller may omit both. Without such an ancestor, both are required. The dispatcher stores the operation and expected head before it calls the authenticated Source Control owner's POST /merge-intents route. An approval pending response leaves the checkpoint running and dependents blocked. After the exact approval is recorded, a later dispatch recovers that same intent through POST /merge-intents/{intentId}/execute. The Merge gate succeeds only after the owner returns the matching repository, PR, head, method, approval evidence, and durable merge SHA, which the Orchestrator stores as a compact receipt.

Backlog claims ​

Native owner prefix: /api/projects/{projectId}/runs/{runId}/backlog. Graph reads, task creation, state/archive changes, and dependency edits also have project-scoped operations described above. The Gateway and MCP expose the claim operation at /api/v1/projects/{projectId}/runs/{runId}/backlog/tasks/{taskId}/claim. Claims use the current accepted run selection and Coordination authority. The Gateway also exposes work-plan promotion preview and confirmation. These promotion routes are not available through MCP.

MethodSuffixPurpose
GET/Read backlog and readiness.
POST/tasksAdd task.
PUT/tasks/{taskId}/stateChange task state.
POST/tasks/{taskId}/archiveArchive task.
PUT/tasks/{taskId}/dependencies/{prerequisiteTaskId}Add dependency.
DELETE/tasks/{taskId}/dependencies/{prerequisiteTaskId}Remove dependency.
POST/tasks/{taskId}/claimAtomically claim eligible work with current prerequisite evidence.
GET/promotions/preview?rootSessionId={rootSessionId}Read the current confirmed work plan without changing the backlog.
POST/promotionsPromote the run's confirmed work plan into backlog tasks after explicit confirmation.

Plan promotion and task origin ​

The Gateway exposes these promotion routes at /api/v1/projects/{projectId}/runs/{runId}/backlog/promotions/preview and /api/v1/projects/{projectId}/runs/{runId}/backlog/promotions. Both require current Coordination authority and the accepted run selection. They are Gateway-only routes and are not MCP tools.

The preview request requires the rootSessionId query parameter. It returns the current rootSessionId, workPlanId, decisionStateVersion, executionFence, and items. Each item contains its stable workPlanItemId, title, task, and dependsOn IDs. The preview does not write to the backlog. It does not read local files or call a model.

POST /promotions turns the current confirmed work plan of a coordinator run into backlog tasks. The body contains rootSessionId, workPlanId, expectedDecisionStateVersion, expectedExecutionFence, expectedGraphRevision, and idempotencyKey (1-128 characters). The Board sends the graph revision it currently displays. The owner checks that the revision, confirmed plan, execution fence, and decision version are current, and that the run has no registered children and no MAF dispatch records.

Each plan item becomes one open task. The task title is the item title and the description is the item task text. The task ID is plan- followed by 32 lowercase hexadecimal characters of a SHA-256 hash of the length-prefixed project, run, plan, and item IDs. Each item dependency becomes a task dependency. The tasks, edges, promotion record, and one origin record per task commit in one transaction. The decision state does not change. After promotion, MAF dispatch rejects the promoted plan with maf_execution_dispatch_stale.

A retry with the same key and values returns the stored promotion. The response is a BacklogPlanPromotion with promotionId, projectId, runId, rootSessionId, workPlanId, workflowId, workflowRevision, decisionStateVersion, executionFence, graphRevision, promotedAt, and tasks (taskId and workItemId, ordered by workItemId). A completed identical retry returns its stored result before the owner reads the current decision or selection context. The owner still checks current authority.

The owner commits the tasks, dependencies, promotion record, and task origins in one transaction. A denied request, failed write, or stale graph or plan conflict leaves the backlog unchanged.

CodeStatusMeaning
backlog_promotion_invalid400A required value is missing or out of range.
backlog_promotion_stale409The plan, decision version, or fence is no longer current.
backlog_promotion_run_started409The run has children or dispatch records.
backlog_promotion_conflict409The plan was already promoted with another key.
backlog_promotion_idempotency_conflict409The key was used with different values.
backlog_promotion_selection_unavailable409The pinned selection context is missing.

A stale graph revision returns 409 with typed backlog issues.

A claim request contains expectedGraphRevision, expectedTaskRevision, and an idempotencyKey of 1-128 characters. The owner binds that key to the task, the accepted selection snapshot, actor, and run. Retrying the same request returns the stored claim and root-session identity; reusing the key with different inputs returns 409. The task claim, accepted root, initial decision, and outbox intent commit in one Orchestrator transaction. The Gateway does not return an accepted claim if prerequisite evidence, run admission, or current authority checks fail before commit. The Events session is registered after the transaction. If that registration fails, the task claim is still durable; retry the same request with the same key to recover the receipt and retry registration. This does not promise exactly-once external effects or start an automatic scheduler.

When the run already has an accepted coordinator root, the server uses that root for the claim. An exact retry returns the same claim and root; it does not create a second root. A conflicting run or selection fails instead of moving the claim to another root.

The claim reserves a coordinator root against the run's accepted workflow and immutable selection snapshot. Its preparing phase is a reservation state, not proof that work has been dispatched or completed. Subsequent coordination and dispatch use the existing Orchestrator workflow owner.

Two native project routes read the recorded data with current ReadProjects authority:

MethodPathResponse
GET/api/projects/{projectId}/backlog/promotions{ promotions }, oldest first.
GET/api/projects/{projectId}/backlog/origins{ origins }, ordered by task ID.

A BacklogTaskOrigin contains task (projectId and taskId), promotionId, runId, rootSessionId, workPlanId, and workItemId. Tasks added by ordinary capture or the run POST /tasks route have no origin record. Migration 030_backlog_task_origin.sql must be applied before these routes work. Applying the migration, granting access to the new tables, and accepting the changed PostgreSQL plan hash each require separate operator approval.

Source Control ​

Native prefix: /api/projects/{projectId}/runs/{runId}/source-control/sessions/{sessionId}. Gateway prefix: /api/v1/projects/{projectId}/runs/{runId}/source-control/sessions/{sessionId}.

These routes require Coordination authority and current Source Control selection/pins. Gateway routes require an explicit X-Agentweaver-Tenant. Merge operations also validate the current merge gate and intent. Output-capture reads return only admitted captures. The Gateway forwards the X-Source-Control-Output-Sha256 file header and allows up to 64 MiB for capture reads, because a capture can hold a 32 MiB manifest and 16 MiB files.

MethodSuffixPurposeGateway
POST/pinPin repository; optional App selectionCode, or legacy secret mode with no body.Yes
POST/issuesCreate repository issue.Yes
POST/pull-requestsCreate or reuse pull request.Yes
GET/pull-requests/{pullRequestNumber:long}/reviewsRead reviews.Yes
POST/workspacesPrepare pinned repository workspace.Yes
POST/workspaces/{workspaceId}/diffRead repository diff.Yes
POST/workspaces/{workspaceId}/output-capturesCapture verified produced output.Yes
GET/output-capturesRead capture page.Yes
GET/output-captures/{captureId}Read capture metadata.Yes
GET/output-captures/{captureId}/diffRead captured diff.Yes
GET/output-captures/{captureId}/filesRead exact captured file.Yes
POST/merge-intentsRequest approval for merge intent.Yes
GET/merge-intents/{intentId}Read merge intent.Yes
POST/merge-intents/{intentId}/executeExecute approved intent.Yes
POST/webhook-relayAdmit owner-authenticated relayed webhook.No
MethodFull native pathAuthPurpose
GET/internal/projects/{projectId}/runs/{runId}/source-control/sessions/{sessionId}/output-captures/{captureId}/proofCoordination; exact capture and selectionProvide proof to Events.
POST/api/source-control/github/webhookBearerExplicitly reject direct GitHub webhook delivery.

Private coordination and runtime ​

Native-only prefix: /internal/projects/{projectId}/runs/{runId}/coordination.

MethodSuffixAuthPurpose
POST/message-routeCoordination; Events audienceValidate message route.
GET/sessions/{sessionId}/owner-bindingCoordination; Events audienceRead current session binding.
POST/sessions/{sessionId}/fork-admissionCoordination; Events audienceValidate fork admission.
GET/sessions/{sessionId}/runtime-owner-contextRuntimeRead current mapped runtime owner context.
GET/sessions/{sessionId}/runtime-execution-observationRuntimeRead current execution observation.
GET/sessions/{sessionId}/runtime-execution-observation/v2RuntimeRead version 2 observation.
POST/sessions/{sessionId}/runtime-registrationsRuntimeRegister accepted placement and runtime binding.
GET/sessions/{sessionId}/runtime-registrationsRuntimeRead session registration.
GET/sessions/{sessionId}/usage-receipts/{receiptId:guid}RuntimeRead immutable native usage source receipt.
GET/sessions/{sessionId}/usage-dispatch-completions/{dispatchId:guid}RuntimeRead dispatch completion evidence.

Native-only prefix: /internal/runtime. All routes below use Runtime authority and the exact current registration, proof, action, turn, or receipt binding.

MethodSuffixPurpose
GET/registrations/{runtimeInstanceId:guid}Read current registration.
GET/registrations/{runtimeInstanceId:guid}/skillsRead accepted runtime skill material.
POST/actions/authorizeAuthorize action and commit guarded admission. Returns HTTP 428 with runtime_guardrails_content_required when ordered Guardrails checks apply to a model turn.
POST/actions/authorize-contentAuthorize a model turn with its exact UTF-8 text so the ordered Guardrails checks can run. The text is never stored.
POST/actions/verifyRevalidate action proof.
POST/actions/credit-denials/readRead action credit denial.
POST/actions/numeric-denials/readRead an immutable numeric-limit denial by attempt.
POST/execution/replacements/compareValidate a current owner-bound setup or Core invocation and read matching dispatch, checkpoint, and result facts; remain blocked until required Environment and Host/Events evidence is available.
POST/remote-tool-results/verifyVerify reviewed remote result proof.
GET/sources/{runtimeInstanceId:guid}Read current native usage source.
POST/sources/{runtimeInstanceId:guid}Save source facts.
POST/observationsRecord runtime observation.
POST/turns/beginAdmit turn.
POST/turns/denials/readRead native credit denial.
POST/turns/fixed-credit-denials/recordRecord fixed-credit denial.
POST/turns/fixed-credit-denials/readRead fixed-credit denial.
POST/turns/fixed-credit-denials/select-currentSelect only the unique complete fixed-credit pair for the authenticated current registration and source grant; no request ID or hash selector.
POST/credit-guards/readRead current credit guard.
POST/turns/fixed-credit-denials/no-sendRecord fixed-credit no-send evidence.
POST/turns/no-sendRecord no-send evidence.

Replacement comparison accepts only the current setup or Core invocation stored in the Orchestrator owner binding. It rechecks current registration, Projects selection, and invocation authority around the read. The response may include the original and current runtime registrations, the stored checkpoint and parent metadata, and a digest of a stored result. Missing result data remains an explicit provenance gap. The comparison always remains blocked: these facts do not establish Environment replacement lineage or a Host/Events effect and cursor receipt, and the read writes no success receipt. | POST | /turns/observations | Save turn observation. | | POST | /turns/accounting | Record accounting acknowledgment. | | POST | /turns/recorded | Record durable turn completion evidence. | | POST | /suspend/require-current | Validate current suspend operation. | | POST | /suspend/release/require-current | Validate placement release. | | POST | /resume/require-current | Validate current resume. | | POST | /resume/require-bootstrap-current | Validate current resume bootstrap. |

Numeric-denial writes and reads require migration 039. During an accepted pre-migration rollout, these routes fail with database_update_pending (503); they do not return or persist a denial receipt without the append-only ledger.

Runtime registration, usage, and suspend/resume helper mappings depend on the host's enabled runtime composition. A route mapping is not proof of a registered native SDK session or an available provider.

Knowledge ​

Source: services/knowledge/Agentweaver.Knowledge/KnowledgeEndpoints.cs.

Project-wide native prefix: /api/projects/{projectId}/knowledge. Project-wide Gateway prefix: /api/v1/projects/{projectId}/knowledge. Project-wide search requires an unbound Broker token with current project AccessPrivateKnowledge and direct project ReadRunSelection. It searches all agents through existing provider bindings and does not create a new binding. Run-bound tokens are rejected. Results are globally ordered across provider resources before paging. Each item includes accessRunId, the run binding used to authorize revision-history reads; record.sourceRunId is separate record provenance.

MethodSuffixAuthPurpose
GET/recordsPrivate Knowledge and direct project ReadRunSelectionSearch all agents across existing run-provider bindings by kind, q, includeInactive, page, and pageSize. The optional state=pending requires kind=proposal and counts pending proposals even when includeInactive=false; other state filters are not supported. Each result includes the access run for history reads; record provenance is separate.

Native prefix: /api/projects/{projectId}/runs/{runId}/agents/{agentId}. Gateway prefix: /api/v1/projects/{projectId}/runs/{runId}/agents/{agentId}. Every route in this table is in the Gateway catalog.

MethodSuffixAuthPurpose
POST/recordsPrivate KnowledgeCreate record.
GET/recordsPrivate KnowledgeSearch by kind, q, includeInactive, page, and pageSize.
GET/records/{recordId:guid}Private KnowledgeRead exact agent record.
PUT/records/{recordId:guid}Private KnowledgeRevision-checked correction, archive, or supersession.
GET/records/{recordId:guid}/revisionsPrivate KnowledgePage immutable revisions.
POST/records/{recordId:guid}/restorePrivate KnowledgeAppend restored revision.
POST/records/{recordId:guid}/approvePrivate KnowledgeApprove eligible Decision.
GET/records/exportPrivate KnowledgeExport exact-scope bundle.
POST/records/importPrivate KnowledgeImport bundle, up to 1 MiB.
POST/proposals/{proposalId:guid}/promotePrivate Knowledge; existing binding and owner effect checksPromote Proposal.
POST/proposals/{proposalId:guid}/rejectPrivate KnowledgeReject Proposal.
GET/contextPrivate KnowledgeCompile context using q, maxItems, and maxTokens.

All writes require one valid Idempotency-Key header. Reads do not.

MethodNative-only full pathAuthPurpose
GET/internal/accepted-effects/{receiptId:guid}Current WriteProjects authority, exact receipt actor/tenant/bindingRead accepted-effect receipt.
GET/internal/projects/{projectId}/runs/{runId}/accepted-effects/{receiptId:guid}Same authority plus exact route scopeRead scoped receipt.

See Knowledge and Memory.

Events & Sessions ​

Source: services/events-and-sessions/Agentweaver.EventsAndSessions/.

Journal ​

Native-only prefix: /internal/sessions. All routes require Journal authority and exact project/run claims.

MethodSuffixPurpose
POST/{sessionId}Create session and persist provider binding.
POST/{sessionId}/eventsAppend typed event; generic writes cannot bypass trusted-writer requirements.
POST/{sessionId}/forkCreate explicit-event fork after Orchestrator admission.
POST/{sessionId}/policy-evaluationsFetch, validate, and append immutable policy receipt.
GET/{sessionId}/eventsReplay bounded event page.
GET/{sessionId}/events/liveStream bounded NDJSON deliveries.
MethodNative full pathAuthPurposeGateway full path
GET/internal/projects/{projectId}/runs/{runId}/eventsJournalReplay committed run journal./api/v1/projects/{projectId}/runs/{runId}/events
GET/internal/projects/{projectId}/runs/{runId}/project-history/eventsReadRead run activity with current project read authority and tenant ownership checks./api/v1/projects/{projectId}/runs/{runId}/history/events
GET/internal/projects/{projectId}/runs/{runId}/events/liveJournalNative NDJSON stream.No; Gateway SSE uses replay instead
GET/internal/projects/{projectId}/runs/{runId}/sessions-provider-bindingExact bound ReadRunSelection authority and current providerRead immutable Sessions pin.No
GETNo native SSE routeExact run bearer and current Gateway/owner access checksSSE over committed replay pages./api/v1/projects/{projectId}/runs/{runId}/events/live

Historical turn text ​

GET /api/v1/projects/{projectId}/runs/{runId}/sessions/{sessionId}/turns/{eventId} returns { eventId, identity, text } from the existing Events material owner. Use the event and session identities from a committed turn event. The native route is GET /internal/sessions/{sessionId}/turns/{eventId:guid}.

The caller needs an exact run-bound bearer and current project read authority. The owner rechecks authority after reading stored bytes. Responses use Cache-Control: no-store. Missing history returns 404; lost access returns 403. The route reads only turn text. It does not accept a material kind or expose object keys, runtime configuration, SDK cache, or remote-tool results.

Material, messages, and accepted facts ​

The following routes are native-only. Runtime/material routes recheck current Projects, Orchestrator, and provider state. Trusted peer checks are additional to bearer authentication where configured.

MethodFull pathAuthPurpose
POST/internal/runtime/resume/configurationRuntimeResolve private resume configuration.
POST/internal/sessions/{sessionId}/runtime-configurationRuntime; accepted configuration bindingStore private runtime configuration material.
POST/internal/sessions/{sessionId}/materialRuntime; typed current material admissionAppend typed turn/tool/cache material.
GET/internal/sessions/{sessionId}/material/{eventId:guid}/{kind}Runtime; material-specific current read authorityRead exact typed material.
POST/internal/sessions/{sessionId}/remote-tool-resultsRuntime; trusted reviewed-result producer/proofStore private reviewed remote tool result.
POST/internal/sessions/{sessionId}/remote-tool-results/readRuntime; exact reviewed-call proofRead private reviewed result.
POST/internal/sessions/{sessionId}/produced-run-captures/{captureId}Journal and Source Control proofAdmit produced output package.
GET/internal/sessions/{sessionId}/produced-run-captures/events/{eventId:guid}Journal and current capture authorityRead captured output by event.
POST/internal/project-facts/accepted-effectsBearer and current Knowledge accepted-effect receiptAdmit project accepted-effect fact.
POST/internal/addressed-messages/admitJournal and current Orchestrator route admissionAdmit owner-routed message.
POST/internal/addressed-messages/projects/{projectId}/runs/{runId}/sessions/{sessionId}/claimJournal; current recipient fenceClaim next message.
POST/internal/addressed-messages/projects/{projectId}/runs/{runId}/sessions/{sessionId}/messages/{messageId:guid}/presentJournal; exact claim and owner admissionMark presented.
POST/internal/addressed-messages/projects/{projectId}/runs/{runId}/sessions/{sessionId}/messages/{messageId:guid}/acknowledgeJournal; exact claim and owner admissionAcknowledge delivery.

Native usage ​

These routes are registered when EventsAndSessions:RuntimeUsage:Enabled is true. They require exact bound ReadRunSelection authority; write/admission routes additionally validate current immutable runtime source evidence.

MethodNative full pathPurposeGateway full path
POST/internal/projects/{projectId}/runs/{runId}/usage/copilot-run-admissionAdmit Copilot run cost binding.No
POST/internal/sessions/{sessionId}/usage-receiptsAdmit reference-only source receipt.No
POST/internal/runtime/sources/{runtimeInstanceId:guid}/cost-preflightCheck current pinned cost source.No
GET/internal/projects/{projectId}/runs/{runId}/usageRead persisted run usage totals./api/v1/projects/{projectId}/runs/{runId}/usage
POST/internal/projects/{projectId}/runs/{runId}/usage/copilot-cost-snapshotRead current Copilot cost snapshot.No

See events for wire shapes and Events & Sessions for admission rules.

Environment ​

Source: services/environment/Agentweaver.Environment/. These are native owner routes, not Gateway or first-party MCP operations.

Lifecycle and egress ​

MethodFull pathAuthPurpose
POST/api/projects/{projectId}/runs/{runId}/environmentsEnvironment write and ReadRunSelectionEnroll Environment owner state.
POST/api/projects/{projectId}/runs/{runId}/environments/{environmentId}/releaseEnvironment write and ReadRunSelectionRelease fenced owner state.
GET/api/projects/{projectId}/runs/{runId}/environments/{environmentId}/lifecycleEnvironment readInspect lifecycle.
POST/api/network-egress/applyEnvironment write and ReadRunSelectionApply accepted egress intent.
POST/api/network-egress/verifyWriteProjects and ReadRunSelectionRead-only verification of the exact Environment fence, policy generation, and authorized selection revision.
POST/api/network-egress/revokeEnvironment writeRevoke owned policy.
POST/api/network-egress/reconcileEnvironment write and ReadRunSelectionReconcile recorded uncertain effect.
POST/internal/provider-lifecycle/reportsBearerReturns 503 environment_provider_lifecycle_unavailable; report ingestion is not implemented.

Workspace volumes ​

For invocation-bound Environment creation, use the authenticated internal Environment creation routes, not the public routes below. They require exact run-bound ReadRunSelection, a current Core invocation binding, and retained Environment/volume creation links. They do not grant run-bound callers public WriteProjects authority. p1Binding contains the exact expected invocation IDs, receipt and selection hashes, root session, and execution fence. Missing or changed evidence fails closed before new creation mutations; no fallback to ordinary creation occurs.

Prefix: /api/projects/{projectId}/runs/{runId}/environments/{environmentId}/workspace-volumes. GET uses Environment read authority. Writes use Environment write authority and ReadRunSelection; flush also validates the trusted runtime and exact Workspace generation.

MethodSuffixPurpose
GET/{volumeId}Inspect volume.
POST/{volumeId}Create volume owner record.
POST/{volumeId}/provisionProvision selected resource.
POST/{volumeId}/replaceReplace exact resource generation.
POST/{volumeId}/bindBind volume.
POST/{volumeId}/unbindUnbind volume.
POST/{volumeId}/releaseRelease eligible resource.
POST/{volumeId}/flushVerify trusted durable flush.
POST/cleanup/retryRetry recorded cleanup.
POST/cleanup/{sourceReplaceOperationId:guid}/reconcileReconcile exact old-resource cleanup.

Sandbox and BuildTest ​

Prefix: /api/projects/{projectId}/runs/{runId}/environments/{environmentId}/sandbox. Except for the two placement projections, every route below requires Environment write authority and ReadRunSelection, including GET inspection routes. BuildTest also validates accepted checkpoint/command evidence and the current Sandbox, network, and Workspace binding.

MethodSuffixAuthPurpose
POST/provisionEnvironment write and ReadRunSelectionProvision exact accepted Sandbox lease.
GET/Environment write and ReadRunSelectionInspect lease at requested network-policy generation.
GET/v1/placementEnvironment writeRead actor-safe placement.
GET/v1/internal/placementExact run-bound ReadRunSelectionRead run-bound placement.
GET/v1/operations/{operationId:guid}/provider-attemptsEnvironment write and ReadRunSelectionInspect provider attempt evidence.
GET/v1/late-resource-cleanupsEnvironment write and ReadRunSelectionInspect late-resource cleanup.
GET/build-test/binding-preparationEnvironment write and ReadRunSelectionRead accepted command binding preparation.
POST/build-test/commandsEnvironment write and ReadRunSelectionDispatch accepted BuildTest command.
GET/build-test/commands/{operationId:guid}Environment write and ReadRunSelectionRead command operation.
POST/build-test/commands/{operationId:guid}/reconcileEnvironment write and ReadRunSelectionReconcile command.
GET/build-test/commands/{operationId:guid}/workspace-captureEnvironment write and ReadRunSelectionRead verified Workspace output capture.
POST/build-test/commands/{operationId:guid}/workspace-capture/acknowledgeEnvironment write and ReadRunSelectionAcknowledge capture.
POST/abandonEnvironment write and ReadRunSelectionAbandon eligible lease.
POST/reconcileEnvironment write and ReadRunSelectionReconcile uncertain Sandbox effect.

Runtime bootstrap ​

Prefix: /internal/projects/{projectId}/runs/{runId}/environments/{environmentId}/coordination/sessions/{sessionId}/runtime-bootstrap/profiles/{profileId}. All routes use Runtime authority and current Environment placement/profile checks.

MethodSuffixPurpose
GETEmptyRead bootstrap placement context.
GET/readinessRead measured readiness context.
GET/pod-observationRead exact current Pod identity and configuration only; incomplete or mismatched observations return 409. Not invocation ownership or mounted-storage proof.
GET/workspaceRead exact Workspace context.
POST/resolveResolve current registered bootstrap profile.

The Pod observation route uses the same current run-bound Projects authority, Core session context, profile checks, and owner-locked lease as readiness. It returns only SandboxPodObservation, not provider options, recovery descriptors, credentials, or the full readiness context, with Cache-Control: no-store. See Pod configuration observations for identity fields and the actual-versus-configured evidence boundary.

Native-only prefix: /internal/runtime. All routes use Runtime authority.

MethodSuffixPurpose
POST/resume/preparePrepare retained Workspace resume.
POST/resume/verifyVerify resumed Workspace.
POST/resume/bootstrapDeliver resume bootstrap or state-loss receipt.
POST/v1/activateActivate registered runtime.
POST/bootstrap/deliverDeliver owner nonce to configured host.
POST/suspend/resolveResolve trusted suspend and flush state.
POST/suspend/release-placementRelease exact suspended placement.

Remote MCP connections ​

Prefix: /api/projects/{projectId}/remote-mcp/connections. Reads require current ReadProjects; mutations require current WriteProjects. These use bearer-authenticated current Projects authority and revision checks.

MethodSuffixPurpose
GETEmptyList connections.
POSTEmptyCreate connection configuration.
GET/{connectionId:guid}Read current connection.
GET/{connectionId:guid}/configurations/{configurationRevision:long}Read exact configuration revision.
PUT/{connectionId:guid}/identity-bindingAttach revisioned Identity binding.
PUT/{connectionId:guid}Update connection configuration.
POST/{connectionId:guid}/enableEnable connection.
POST/{connectionId:guid}/disableDisable connection.
DELETE/{connectionId:guid}Tombstone connection.
MethodFull pathAuthPurpose
POST/internal/remote-mcp/current-call/verifyRuntime; trusted service and reviewed-call bindingVerify current call authority.
POST/internal/remote-mcp/current-call/dispatchRuntime; trusted Orchestrator peer and current-call proofValidate request, then return 503 remote_mcp_native_transport_unavailable.

See Environment Sandbox, Environment egress, and Remote MCP connections.

Identity Broker ​

Source: services/identity/Agentweaver.Identity.Broker/. The Gateway BFF tables above also list the exact native Copilot and Remote MCP connection prefixes. Those native endpoints use bearer validation and current owner-scope authorization, not browser local cookies.

OAuth and diagnostics ​

MethodFull pathAuthPurpose
GET/PublicRedirect to /.well-known/openid-configuration with HTTP 302.
GET/connect/authorizeRegistered OAuth client request; local session or external challengeStart PKCE authorization and consent.
GET/connect/authorize/resumeLocal session and one-use resume handleResume saved authorization.
POST/connect/consentBrowser; exact pending consentApprove or decline requested scopes.
POST/connect/tokenOAuth grant/client/PKCE validationExchange code or refresh token; recheck authority.
GET/diagnostics/whoamiBearerRead authenticated subject and scopes.
POST/secrets/redeemBearer; exact current grant, purpose, actor, project/run, and SecretRefRedeem authorized secret version.

The identity middleware also serves its configured OAuth/OIDC metadata and external identity-provider callback. These middleware paths are not new product REST endpoints. See Identity and secrets for registration and authentication configuration.

Direct Repo App browser surface ​

Prefix: /auth/github/repo-app. Registered when the Repo App browser integration is configured. These routes differ from the Gateway bearer BFF. The browser lists repositories directly from Identity Broker and creates a selection using the discovered installationId and repositoryId. The POST uses the local session cookie and an antiforgery token from /csrf, sent in X-CSRF-TOKEN; it returns a short-lived selection code for the Gateway request.

MethodSuffixAuthPurpose
POST/connectBrowser; antiforgery formStart user authorization.
POST/installBrowser; antiforgery formStart App installation setup.
GET/callbackState and transaction cookieComplete user authorization.
GET/csrfBrowserIssue antiforgery token.
GET/statusBrowserRead connection and local credential readiness.
POST/disconnectBrowser; CSRF and expected connection revisionDisconnect local connection.
GET/repositoriesBrowserRead installation/repository metadata.
POST/selectionBrowser; session cookie, CSRF, and current connection revisionExchange installation and repository IDs for a short-lived selection code.

Native POST /internal/source-control/github-app/installations/token requires current bearer/grant and accepted Source Control binding. It mints a repository-scoped installation token inside Identity. It is not a browser route.

Runtime credentials ​

Native-only prefix: /internal/runtime. All routes use Runtime authority, exact current actor/tenant, and the operation's purpose-bound credential or owner grant. Registration is conditional on the runtime credential composition.

MethodSuffixPurpose
POST/model-session/grantIssue current runtime model grant.
POST/model-session/verifyRevalidate model credential receipt.
POST/model-session/redeemRedeem owner-authorized model credential.
POST/bootstrap/requestRequest bootstrap delivery.
POST/bootstrap/verify-pendingVerify pending Configure proof.
POST/bootstrap/consumeConsume Configure nonce.
POST/bootstrap/exchangeExchange current bootstrap proof.
POST/source/verifyVerify source credential proof.
POST/source/rotateRotate source credential.
POST/source/revokeRevoke source credential.

AgentHost ​

The service entry is services/agenthost/Agentweaver.AgentHost/Program.cs. Mappings are in packages/Agentweaver.AgentRuntime/RuntimeAgentHostEndpoints.cs.

The first three paths are configuration-derived. Let configure.AbsolutePath be the path of the host's registered ConfigureEndpoint; no fixed value is implied here. Protected calls require a current bearer for that configure audience and matching request scheme/authority, then exact runtime proof checks.

MethodPath expression or literalAuthPurpose
POSTconfigure.AbsolutePathRuntimeReceive bootstrap nonce.
POSTconfigure.AbsolutePath + "/activate"RuntimeConfigure native session.
POSTconfigure.AbsolutePath + "/resume-state"RuntimeRead private resume bootstrap state.
POST/runtime/v1/refreshRuntimeRefresh host session proof.
GET/runtime/v1/projects/{projectId}/hosted-model-reasoning-catalogAuthenticated project callerRead live hosted levels by model reference with project and binding revisions; no-store.
POST/runtime/v1/turns/fixed-credit-denials/readRuntimeRead fixed-credit guard evidence.
POST/runtime/v1/turns/fixed-credit-denials/select-currentRuntimeSelect the unique complete current fixed-credit guard/no-send pair from the runtime-instance locator; zero or multiple matches return no pair.
POST/runtime/v1/turns/denials/readRuntimeRead native denial evidence.
POST/runtime/v1/turns/numeric-limit-denials/readRuntimeRead one persisted Orchestrator numeric-limit denial for the current registration and attempt; missing receipt is not success.
GET/runtime/v1/readinessRuntimeRead current authenticated readiness.
GET/runtime/v1/readiness/evidenceRuntimeRead current Host/Environment Pod identity and read-only Linux workspace mount evidence. Does not bind invocation ownership or prove storage isolation.
POST/runtime/v1/a2a/message:sendRuntimeAdmit native turn/message send.
POST/runtime/v1/suspendRuntimeSuspend with trusted Workspace handling.
POST/runtime/v1/workspace/resumeRuntimeVerify retained Workspace resume.
GET/health/livePublicProcess liveness.
GET/health/readyPublicMeasured host readiness; 503 on startup or owner failure.

See AgentHost.

MCP ​

services/mcp/Agentweaver.Mcp/Program.cs maps authenticated /mcp through the MCP SDK. It also maps public protected-resource metadata at the audience-derived path and public GET /health/live and GET /health/ready. See MCP tools for transport, scopes, tool arguments, and results.

Shared health routes ​

Projects & Config, Knowledge, Events & Sessions, Environment, Orchestrator, and Identity each map anonymous GET /health/live and GET /health/ready. Their readiness handlers inspect their configured owner database. This is not an end-to-end product check. Gateway and MCP report host availability; AgentHost has separate measured readiness as listed above.

The Web host maps its own health routes and SPA/static paths. See web host reference.

Platform component owner routes ​

Events & Sessions, Environment, Knowledge, Orchestrator, and Identity Broker each map GET /internal/platform/components only when PlatformComponents:ServiceAuthentication is configured. The route accepts only a service token for the private audience whose sub claim equals the configured Projects caller subject. It returns the owner's areas with Cache-Control: no-store, and it's not in the Gateway OpenAPI document. Projects calls these routes for GET /api/platform/components. See Platform components.

Registration and implementation boundaries ​

  • Optional native routes depend on host composition. A public Gateway mapping does not enable an absent owner route.
  • Native Source Control capture/file routes are not Gateway-produced-file APIs.
  • Environment provider lifecycle ingestion and Remote MCP native dispatch explicitly return unavailable responses as listed above.
  • No generic filesystem, arbitrary upstream, or unversioned 0.x /api proxy is added by the Gateway.
  • Gate approval, provider selection, process readiness, and accepted requests report different facts. None substitutes for completed runtime execution.