Skip to content

Control API reference

Agent notes

The installed server is the truth: run introspection or astro api graphql -q 'query { astroliftServerInfo { version capabilities } }' before trusting this page, and read the SDL at backend/schema.graphql in calliopeai/astrolift-app (pin a tag or SHA). Fields the SDL marks @deprecated (for example astroliftWebhookSubscriptions, capped at 200 rows) have a named replacement; prefer it. A capability key only says a surface exists, never that this credential may use it. Common mistakes: omitting X-Astrolift-Organization when the identity belongs to several organizations; reading data without checking ok and errors on a mutation envelope; passing a slug where the schema types a GUID.

Domain setup reads include an exact GUID/version query, astroliftManagedDomainDiagnostics and astroliftManagedDomainProbe. They separate provider inventory, public delegation, recorded routes and bounded network observations, with current domain permissions and explicit unavailable states. See Domains and DNS for query examples.

Exact service email diagnostics use emailDeliveryTestSupport, sendEmailDeliveryTest and cursor-paginated emailDeliveryTestsPage. A stable request UUID recovers the original send intent; provider acceptance, uncertain acceptance and signed delivery observations remain separate. The support query is advisory source/write admission, not native deliverability certification. See Email delivery for reviewed versions, current permissions, suppression and read-only recovery.

Install SMTP diagnostics use installAlertMailSupport, sendInstallAlertMailTest and cursor-paginated installAlertMailTestsPage. They require current platform operator and organization admission, a reviewed source fingerprint and stable request UUID. Recipient is the caller's registered mailbox; SMTP acceptance is not delivery. See install alert SMTP.

Cloudflare setup uses dnsProviderConnectionSupport, versioned dnsProviderConnectionsPage, cloudflareDnsZones and cloudflareDnsRecords. registerCloudflareDnsZone creates a read-only registration; attachCloudflareDnsZone preserves an existing writer. dnsProviderDomainBinding recovers the protected tuple and exact canVerify hint. These operations add no DNS or registrar writer. See Cloudflare setup.

Astrolift's typed control-plane API is GraphQL. Focused REST, SSE, and WebSocket routes exist where device authentication, callbacks, streaming, or CI semantics do not fit GraphQL well.

The temporary-app guide covers registerApp and hostAppOnBrain creation deadlines, setAppExpiry and the organization's expiry policy. Require apps.temporary_expiry in server discovery before using those fields. Agent conversations use astroliftAgentMessages, astroliftAgentMessageThreads, markAgentMessagesRead, replyToAgentMessage and astroliftAgentMessageReceived; require agents.messages and the caller's current agent access.

With notifications.quiet_hours, astroliftMyNotificationQuietHours and setNotificationQuietHours let the authenticated person configure agent-message email and push suppression. The inbox guide documents the IANA timezone and minute boundaries; quiet hours do not mark messages read or create a digest.

With notifications.structured_inbox, astroliftMyNotificationsPage and astroliftMyNotificationStream provide bounded, cursor-based platform notification reads.

Base URLs

Builder source-to-brain hosting uses bearer REST under /api/builder/v1/. Require builder.brain_source_artifacts, then inspect authenticated Builder capabilities and the operator-prepared project target. Build admission freezes source into a verified artifact; a fresh original-person host/ request creates the app/binding/deployment. See source-to-brain hosting for exact routes, request fields, ephemeral SQLite and recovery boundaries.

Given an install at https://astrolift.example.com:

Surface URL
GraphQL HTTP/explorer https://astrolift.example.com/app/gql/config/
Anonymous installation discovery https://astrolift.example.com/app/gql/config/public/
GraphQL subscriptions wss://astrolift.example.com/app/gql/config/ws/
CLI device flow https://astrolift.example.com/api/cli/v1/auth/{start,complete,refresh,signout}
CI deploy (deploy token) https://astrolift.example.com/api/cli/v1/apps/<app-slug>/deploy/
Builder source-to-brain https://astrolift.example.com/api/builder/v1/
Agent dispatch controller https://astrolift.example.com/api/dispatch/v1/
MCP https://astrolift.example.com/api/mcp/v1/
Health https://astrolift.example.com/health/

The dispatch controller is called by running agents with task-scoped keys, not by people; see the agent architecture. The CI deploy route is shown in monorepo CI.

Before login, POST query { astroliftServerInfo { version apiVersion capabilities } } to the public discovery endpoint without bearer, organization or cookie headers. Its schema exposes only installation discovery and has no mutation or subscription root. The main GraphQL endpoint still requires authentication; do not probe it as an anonymous fallback. A capability advertises an API surface and grants no permission to use it.

The server root returns a link map when requested as JSON:

curl -sS -H 'Accept: application/json' https://astrolift.example.com/

Authentication and tenancy

User API tokens start with alft_at_. App-scoped deploy tokens start with alft_dt_ and are accepted only by their intended CI/deploy routes. Task-scoped alft_cb_ callback keys are minted per agent dispatch and accepted only by the dispatch controller routes of that one task.

Authorization: Bearer alft_at_...
X-Astrolift-Organization: <organization-guid>
Content-Type: application/json

The organization header selects one organization when the identity belongs to more than one. Never use a slug where the API requires a GUID. The token's scopes narrow the user's RBAC grants; requests must pass both checks.

The reviewed server scope catalogue includes read:apps, write:apps, read:clusters, write:clusters, manage:clusters, read:zentinelle, manage:auth-users, write:app-access, agent-env-spec:write, project:write, team:write, app:onboard, secret:read, secret:write, workflow:write, workflow:trigger, mcp:read, mcp:dispatch, mcp:write, and admin. The selected installation's token catalogue is authoritative; a listed scope is not necessarily part of the default device-flow credential. Use the smallest set that supports the integration. astro auth login --scope selects documented CLI profiles (clusters, zentinelle for read-only Zentinelle access on servers advertising identity.zentinelle_read_scope, and admin, a 12-hour platform operator sign-in), not an arbitrary comma-separated scope list. Account grants from astro whoami --permissions --json are informational and cannot establish this credential's ceiling or exact target authority.

GraphQL request

ASTROLIFT_TOKEN is an alft_at_ token minted under Settings > API tokens (or astro auth login, whose stored credential astro api graphql reuses). ASTROLIFT_ORG_ID is the organization GUID from astro org current --json (id), never its slug.

curl -sS https://astrolift.example.com/app/gql/config/ \
  -H "Authorization: Bearer $ASTROLIFT_TOKEN" \
  -H "X-Astrolift-Organization: $ASTROLIFT_ORG_ID" \
  -H 'Content-Type: application/json' \
  --data-binary @- <<'JSON'
{
  "query": "query { astroliftServerInfo { version serverTime capabilities } }",
  "variables": {}
}
JSON

Expected: HTTP 200 with data.astroliftServerInfo.version set. HTTP 401 means the bearer token is missing, malformed, expired or revoked; mint or refresh it. HTTP 200 with an errors entry whose extensions.code is PERMISSION_DENIED means the credential is valid but the organization header, token scope or RBAC grant does not cover the field (see permission refusals).

A successful HTTP response can still contain GraphQL errors; check that array before reading data. Mutations generally return an envelope with ok, structured errors, and data. Do not treat HTTP 200 as mutation success without checking ok.

The installation's explorer and introspection expose the exact schema supported by that server. The platform repository also publishes schema.graphql for client generation. Prefer generated types or committed operations over building query strings from user input.

Generated contracts and drift checks

The release source publishes the GraphQL SDL and the MCP capability superset. Replace main in those URLs with an immutable backend tag or commit SHA when pinning a client build.

Platform contributors regenerate both artifacts with make contracts and verify them with make contracts-check. CI assembles the full-feature Strawberry schema, byte-compares the backend/frontend SDL, validates every MCP input JSON Schema, checks MCP metadata against live handlers, regenerates frontend GraphQL types, and rejects any diff.

This is not yet a generated catch-all OpenAPI document. Most focused REST routes still define payloads imperatively, so route introspection would publish names without truthful request, response, and authorization schemas. REST OpenAPI will be generated as those endpoints adopt shared typed contracts.

Native model connection operations

Compatible servers advertising models.bedrock_connections expose bounded bedrockModelSources and exact bedrockModelSource reads, with separate installation/operator bedrockModelConnectionSupport and exact-placement bedrockModelConnectionAction admission. registerBedrockModelConnection, updateBedrockModelConnection and unregisterBedrockModelConnection manage a local existing-source connection record, returning the existing ClusterModelDeploymentMutationResult envelope. They do not allocate or delete native AWS model resources. Every write requires current hosting authority and reviewed target versions/source identity; registration has no generic GraphQL idempotency guarantee. See native model connections for the read-only CLI documents, binding and reconciliation boundaries.

models.native_connection_metadata adds ClusterModelDeployment.nativeConnection to inventory and detail reads under their existing permissions. Its family and source-kind enums distinguish Bedrock foundation models/inference profiles, Vertex Endpoints, Foundry deployments and unknown native records. The NativeConnectionSource union carries provider-specific metadata; a null source with UNAVAILABLE preserves the native distinction. Local hosted records return null for nativeConnection.

Existing Bedrock records populate this projection. The Vertex/Foundry union types do not implement adoption or app connection operations. Invocation access remains UNKNOWN; resource and reviewed-source fingerprints are metadata hashes, not ownership or inference proofs. This marker is independent of the Bedrock implementation marker and default-off runtime flag. See the native connection guide's typed query for the exact fields.

Compatibility

  • Query server capabilities before assuming an optional module exists.
  • Additive GraphQL fields are backward compatible; clients should ignore response fields they do not understand.
  • Pin a CLI/SDK version in unattended automation.
  • Use idempotency keys on deploy routes when retrying after a network failure.
  • Expect 401 for invalid/expired credentials and permission errors when RBAC or the token scope ceiling denies the action.

There is no single catch-all REST/OpenAPI surface for control-plane CRUD. Use GraphQL unless a documented workflow explicitly names a REST, SSE, or WebSocket route. This avoids depending on internal Django paths.

Browser elevation and bearer admission

A compatible server can require recent authentication for sensitive browser mutations. Handle STEP_UP_REQUIRED using its supportedMethods and requiresAttestation fields; a CLI confirmation, account permission list or successful metadata read is not that proof. The existing browser-recency gate does not apply to API-token calls, which retain their bearer and scoped-grant gates. Reviewed workflow reservation, dispatch and recovery additionally refresh identity, membership, token ceiling, policy and ownership after lock waits. See the reviewed-start SSO setup for exact callback registration, identity-link and session requirements, time limits and refusal recovery. No new capability key or CLI elevation verb is assumed for this admission repair.

Secrets

Secret-list operations return names, references, and presence metadata. A caller needs secret:read plus secret.read RBAC to reveal a value on the few surfaces that support reveal. secret:write permits write-through operations, not readback. MCP intentionally never exposes secret values.

Reviewed team membership

The prepared additive contract advertises identity.reviewed_team_membership. Check the installed server's capability list and SDL before requesting it. See membership setup for the browser flow and remaining-access rules.

Operation Purpose
astroliftTeamMembershipTeam(teamId, slug) Resolve exactly one live, visible team GUID or route slug.
astroliftTeamMembershipPerson(orgMemberId) Read the exact visible organization identity.
astroliftTeamMembershipsPage(teamId, search, page, pageSize) Page a team's roster and direct/inherited/provider provenance.
astroliftPersonTeamMembershipsPage(orgMemberId, search, page, pageSize) Page the person's currently visible teams.
astroliftTeamMemberCandidatesPage(teamId, search, page, pageSize) Select active existing organization members.
astroliftMembershipTeamsPage(search, page, pageSize) Page the caller's manageable team targets.
astroliftTeamMembershipRolesPage(teamId, search, page, pageSize) Page eligible team roles under the current grant ceiling.
astroliftTeamMembershipReview(teamId, orgMemberId, kind, roleId) Review ADD or REMOVE; return the exact expectedSource digest.
changeAstroliftTeamMembership(input) Commit or recover one reviewed direct-membership change.

For example, save this read-only query as team-roster.graphql and GUID variables as team-roster-vars.json, then use astro api graphql --file team-roster.graphql --vars-file team-roster-vars.json:

query TeamRoster($team: GUID!) {
  astroliftTeamMembershipsPage(teamId: $team, page: 1, pageSize: 25) {
    totalCount page pageSize
    items {
      team { id name slug canManageMembers }
      person { orgMemberId name active }
      teamMemberId lifecycle canRemove
      sources { id source scopeKind roleId roleName expired removable }
    }
  }
}
{"team":"00000000-0000-4000-8000-000000000001"}

Replace the placeholder with the team GUID from astroliftTeamMembershipTeam(slug: "<team-slug>") or astro team list --json. Expected: totalCount and an items array; an empty array with HTTP 200 means the team is visible but has no direct members on this page, while a PERMISSION_DENIED error means the caller cannot see that team.

The mutation input carries requestId, kind, teamId, orgMemberId, expectedSource, and roleId for ADD. Obtain the digest from the exact review; do not compute it from roster text. Preserve the original UUID and reviewed input when recovering a lost reply. Successful data distinguishes committed from replayed and returns changeId, exact public GUIDs, removed binding GUIDs and the original remaining sources. Inspect the standard ok/errors envelope and refresh current membership afterward.

Reads and writes check their concrete team/person visibility. Writes refresh credentials, ownership, membership, policy, role ceilings and required browser authentication after waits. Replay is confined to the original actor, organization, credential and reviewed identity. Neither metadata reads nor the advisory me.teamAccessNavigation/team_access hints establish write authority. Existing API-token scope definitions are unchanged.

Agent completion callbacks

runAstroliftAgent accepts optional callbackUrl, callbackSecretRef, correlationId (at most 128 characters), and callbackMode (FULL or NOTIFY), alongside clientRequestId, environmentSpecId, triggerPayload, timeoutSeconds and brainSlugs (semantic layers the run reads as the caller). The organization configures HTTPS destinations with configureAgentTaskCallbacks(allowedHosts) and writes a signing secret with setAgentTaskCallbackSecret(name, value). Query agentTaskCallbackPolicy for the configured host allow-list. Never send the signing key in dispatch input.

agentTask returns callbackStatus, callbackAttempts, and callbackLastError. redeliverAgentTaskCallback(taskId) replays the final event without rerunning the agent. Read the completion callback guide for the exact signed wire contract, durable 24-hour backoff, authorization, retention, rotation, and Python verification snippet.

Semantic layers (brains)

Hosted semantic layers are apps of a brain kind. astroliftBrainsPage, astroliftBrain(slug), astroliftBrainStatus, astroliftBrainCells, astroliftBrainEdition and astroliftBrainCreation(id) read them; createBrain, rebuildBrain, updateBrainSubstrate, shareBrain, unshareBrain and archiveBrain manage them, and hostAppOnBrain creates a hosted app bound to one. issueBrainReadToken(slug) returns a 15-minute read token and the X-Astrolift-Brain-Token header for the brain's /mcp route. astroliftBrainsPage is the bounded form of astroliftBrains. The same operations are exposed as astro brain commands and as MCP tools in the MCP reference.

Bounded workflow authoring and execution metadata

Installations advertising workflows.bounded_review_loops and workflows.serial_collections expose stage maxAttempts, backEdge and iteration on reads and stage create/update inputs. The server validates the combined finite execution budget before dispatch; a capability is not an authorization grant. See bounded workflows for the native object contracts and supported source-import subset.

Stage agent and nested-workflow string references also accept guid:<canonical-lowercase-UUID>. Authoring round-trips preserve explicit GUIDs; unavailable or inaccessible targets are refused without substituting a slug. Literal slugs keep their existing resolution behavior. See the exact-reference rules for binding overrides and visibility checks.

workflowExecutionStages(executionId, limit, after) reads pages belonging to one exact execution GUID or mirror ID. Preserve the returned execution GUID, organization and recorded Temporal workflow/run IDs across pages. Its stage items expose roundNumber, attemptNumber, return causedBy, timestamps, collectionIndex / collectionParentExecutionGuid / collectionStageId, and separate fan-out identities. Item and branch indexes are zero-based. A missing cause/parent remains unknown. complete on a collection means bodies finished under the authored policy, so inspect per-item outcomes rather than assuming all agent results succeeded. Run-control acceptance remains separate from closure and resource cleanup.

Reviewed workflow and pipeline starts

With workflows.atomic_full_review, workflowDefinitionFullReview and workflowScheduleFullReview return atomic complete graph/configuration captures. setWorkflowDefinitionEnabled performs separate revision-bound definition activation. activateReviewedWorkflowSchedule records explicit person consent for the exact configured schedule digest; its saved receipt has engineState: UNCONFIRMED. See complete workflow review for permissions, original versus post-enable digests, current authority and the required worker/API rollout. Schedule consent does not bypass human gates.

workflowDefinitionById(id: GUID!) reads an exact visible definition, execution revision and JSON Schema 2020-12 input contract. startWorkflowDefinition binds the exact GUID, expected revision, schema digest and actor-scoped request UUID; workflowDefinitionStartRequest(requestId) recovers only that original start. Receipts contain execution GUID and recorded Temporal workflow/run IDs. Engine acceptance is separate from workflow completion. Inputs are encrypted on the server and are excluded from recovery metadata and error diagnostics.

startPipelineRun binds an exact pipeline GUID/version/ref and durable request UUID. pipelineStartRequest recovers the original request, and cancelPipelineRun checks the exact run/version/engine identity. Cancellation acknowledgement, execution closure and owned-resource cleanup are independent states. Use bounded run/job/step pages rather than unbounded lists.

See reviewed starts for native CLI commands, permissions, input handling, recovery differences and limits. The target server must expose these fields; there is no legacy-write fallback.

The legacy runWorkflowDefinition alias keeps its original output shape and accepts additive nullable review/confirmation arguments. Missing review proof returns PRECONDITION upgrade guidance with no dispatch. A complete proof uses the same exact durable-start and current-authority gates; new clients should use startWorkflowDefinition rather than relying on slug selection or the legacy mirror-ID field. runAstroliftAgent and configured-workflow APIs retain their separate contracts.

Exact resource, preview and metric context

Use shared services for bounded project resource pages, exact managed-service GUID metadata and separately paged visible consumers. Reviewed writes carry expectedContextRevision; an enqueue acknowledgement is separate from provider completion. Exact preview targets explains persisted environment ownership, versions required on historical and live logs, and preview-export downloads bound to the original requester and credential. Live/export selectors require their advertised additive server capabilities; ordinary legacy exports retain their separate capability-link contract. Workload signals documents each signal's scope, identity basis, physical container membership and instrumentation prerequisites. Check the selected installation's SDL before requesting additive fields.

Environment logs and scoped trace envelopes

Logs and traces describes exact environment selection, shared-cluster placement, paged historical logs and bounded trace/detail reads. Use astroliftAppTracePage and astroliftTraceSpansResult to inspect availability and scope as well as items. Trusted collector attribution is required before trace exposure; a missing collector is not a zero-traffic or successful empty response. These read-only queries can be submitted through astro api graphql; their fields require a compatible server and do not add CLI live/export commands.

Permission refusals

A GraphQL error raised by a permission check carries extensions.code = "PERMISSION_DENIED", extensions.reason and extensions.permission (the permission key, for example org.read). The message is unchanged (<reason>: <permission>). Mutation envelopes use the same PERMISSION_DENIED code. Apps and clusters expose viewerPermissions so clients can offer only what the viewer may do there; the mutation still decides.

Gated sensitive actions can also return STEP_UP_REQUIRED or APPROVAL_REQUIRED, which carries approvalRequestId. See Action safety.

Server-owned cluster keep-alive installation

The prepared astroliftClusterAgentInstallReview(clusterId), installClusterAgent(input) and astroliftClusterAgentInstall(installId) APIs review an exact registered cluster and return version/source proof. Installation requires unchanged expectedVersion and expectedSource, reserves an original request UUID and returns metadata-only installation status. They require cluster.manage, current organization authority and the credential ceiling; shared platform clusters retain their platform-operator gate. No new discovery capability is assumed. Check the actual installation schema before use.

Read the server-owned installation guide for private original-request recovery and heartbeat confirmation. Only SUCCEEDED with heartbeatConfirmed: true establishes installation success; queue acceptance and resource writes do not. This prepared API does not install log collectors or activate tracing.

Prepared reviewed log collector API

Compatible future servers expose astroliftClusterLogCollectorReview, astroliftInstallClusterLogCollector and astroliftClusterLogCollectorOperation. Public capability clusters.reviewed_log_collector_install describes API presence, not grants or health. All target operations require scoped cluster.manage. Review returns an unattached candidate reader policy; original private request recovery and post-pod-loss activation are described in the collector installation guide.

Admin model hosting and source metadata

Model hosting separates catalogue discovery, organization hosting authority, exact repository access, license review, operator-certified CPU/GPU runtime admission and recorded readiness. Compatible servers expose modelHostingAction, bounded huggingFaceConnectionsPage, clusterModelSourceAccess and independent local-artifact metadata/import APIs. Connection reads are metadata-only; the UI submits an HF token through a write-only field and the server stores it encrypted. Local upload authorizations are private capabilities, distinct from immutable manifest metadata. Hosting requires an active installation Super-admin and freshly admitted credentials; organization or team administration alone does not grant hosting authority. Model source/configuration and cluster runtime writes keep that same operator gate. App connections use separate scoped app authority and organization policy. API availability proves neither source access nor a configured object store/hydrator or successful model launch.

clusterModelUpdateAdmission and updateClusterModel review the exact stored source and deployment version before changing hosting settings. Shared models accept independently admitted app connections; dedicated models restrict them to the selected app's environments while remaining organization-owned. astroliftModelSubscriptionMetrics reads one authenticated subscription under current app.read_metrics and organization visibility. Its declared placement and subscription identities must match. It exposes measured traffic, accepted ASGI response bytes and request duration; token use is unsupported by this metrics contract. Use models.authenticated_subscription_metrics for API discovery and the hosting guide's exact read-only query. A capability marker does not grant app access.

models.connection_approvals advertises policy-governed connection intake. modelConnectionTargetsPage and modelConnectionAction return the current AUTO, REQUEST or DENY action. requestModelConnection stores an idempotent reviewed request without connecting the app; reviewers with current org.update and scoped app.approve_deploy can approve or reject. The current requester explicitly invokes finalizeModelConnectionRequest after approval. It rechecks the policy, target versions and distinct live quorum before the subscription is created. Organization policy writes use org.update; model restrictions retain the installation Super-admin hosting gate and only tighten effective policy. See the hosting guide for recovery, request versions and stale outcomes.