Skip to content

Reference

alter apps

Create, inspect, update, archive, and delete applications.

An app owns API keys, provider configuration, agents, and grants. These commands manage the app objects themselves.

alter apps list [--limit <n>] [--offset <n>] [--include-archived] [--no-include-stats]
alter apps create --name <name> [--description ...] [--website-url ...] [--stub]
alter apps show <app-id>
alter apps update <app-id> [--name ...] [--description ...] [--website-url ...]
alter apps legal-profile <app-id> --legal-name ... --privacy-url ... --terms-url ...
alter apps archive <app-id>
alter apps unarchive <app-id>
alter apps delete <app-id> [--confirm <name>]

Reads need dashboard_apps:read; create and update need dashboard_apps:write; legal-profile needs dashboard_apps:write and an organization-admin principal; archive / unarchive need dashboard_apps:admin; delete needs dashboard_apps:delete. Every command except delete accepts --output (delete prints only a confirmation line).

List apps in the current organization.

FlagDefaultDescription
--limit <n>100Page size, from 1 to 1,000.
--offset <n>0Non-negative pagination offset.
--include-archivedoffInclude archived (soft-deleted) apps. Default is active-only.
--no-include-statsstats onSkip per-app grant / connection / secret / provider / key / API-call counts (faster).

The command returns one page as an array. To list every app, keep the same --limit and increase --offset by that amount until a page has fewer rows than the limit. Collect all pages before deleting apps; deleting between pages shifts offsets and can skip rows.

Terminal window
alter apps list
alter apps list --include-archived --output json
alter apps list --limit 200 --offset 200 --no-include-stats --output json

In table output the STATUS column combines the archive state with stub routing: active, archived, active (stub), or archived (stub). JSON and JSONL output carry the is_stub boolean as its own field.

Create a new app.

FlagRequiredDescription
--name <name>yesApp name (maximum 100 characters; control characters rejected).
--description <text>noFree-form description (maximum 500 characters; control characters rejected).
--website-url <url>noFull public website URL (http:// or https://; paths allowed; maximum 2,048 characters; embedded credentials rejected).
--stubnoCreate a stub app — see Stub apps below. Available only on deployments with stub-provider mode enabled.
Terminal window
alter apps create --name "Acme Production" --description "Customer-facing app"

A stub app routes its provider traffic to a stub provider instead of to real third-party providers. It exists so integration and functional tests can drive provider-calling flows — OAuth token exchange, managed-secret preflight, and proxied API calls — without real third-party credentials.

Terminal window
alter apps create --name "ci-fixtures" --stub

Three properties are worth knowing before using it:

  • Stub apps are permanent. --stub is accepted only at creation. There is no alter apps update --stub, and a stub app can never be converted into a normal app or the reverse. An app that changed stub routing mid-life would silently move where its credentials are exchanged, so the choice is fixed for the life of the app. Create a separate app instead.
  • Availability is a property of the deployment, not of the token. No scope or permission grants access to stub apps; --stub rides the same dashboard_apps:write verb as any other create. Stub-provider mode is enabled on staging and preview environments only. Production refuses the setting outright, so a stub app cannot be created against production under any credential.
  • Credential checks against a stub are never reported as verified. Provider and managed-secret preflights that route to the stub return inconclusive or skipped, never passed — a stub cannot vouch for a real credential.

Running --stub against a deployment that does not have stub-provider mode enabled fails with usage code 2 and a message saying so; re-run without --stub to create a normal app.

Show one app by ID.

Terminal window
alter apps show <app-id>

Patch app fields. At least one of --name, --description, or --website-url is required — an empty update is rejected. Names are limited to 100 characters, descriptions to 500, and Website URLs to 2,048. Control characters are rejected in --name and --description; --website-url must be a complete http:// or https:// URL with no embedded credentials.

Terminal window
alter apps update <app-id> --description "Renamed for Q3"

Pass an empty --description or --website-url value to clear that optional field. When Connect sessions omit allowed_origin, Alter derives the browser origin (scheme, host, and port) from website_url.

Stub routing is not patchable — see Stub apps.

Set the Customer identity and policy links Wallet and Connect show to End Users before identity and authorization data is collected. URLs are validated locally and by the backend. Provide at least one support channel.

Terminal window
alter apps legal-profile <app-id> \
--legal-name "Acme, Inc." \
--privacy-url "https://acme.example/privacy" \
--terms-url "https://acme.example/terms" \
--support-email "support@acme.example" \
--agent-purpose "Schedule meetings using the accounts you authorize."
FlagRequiredDescription
--legal-name <name>yesCustomer legal name displayed to End Users.
--privacy-url <url>yesCustomer Privacy Policy (http:// or https://).
--terms-url <url>yesCustomer Terms of Service (http:// or https://).
--support-url <url>one support channelCustomer support URL.
--support-email <email>one support channelCustomer support email.
--agent-purpose <text>noShort description of the application/agent purpose.

Archiving is a reversible soft-delete: the app disappears from the default apps list view but keeps all its keys, grants, providers, and audit history. Because archiving pulls an app out of the default view for the whole organization, both commands require the admin-tier dashboard_apps:admin scope (an organization admin). This is separate from dashboard_apps:delete, which gates the irreversible cascade — :admin does not grant it.

Terminal window
alter apps archive <app-id>
alter apps unarchive <app-id> # 409 if the app isn't archived

Because the cascade is permanent, delete is gated behind the separate dashboard_apps:delete scope (not bundled into :admin) and a type-to-confirm check:

  • Interactive: the CLI prompts you to type the app’s exact name.
  • Non-interactive (CI): pass --confirm <name> matching the app’s name. There is no --yes shortcut — the name must be surfaced so the audit trail records the intent.
Terminal window
# Interactive — prompts for the name
alter apps delete <app-id>
# CI — name supplied explicitly
alter apps delete <app-id> --confirm "Acme Production"

A wrong --confirm value exits 2 (USAGE); declining the interactive prompt exits 8 (CANCELLED).

Provision an app in CI and pin it for later steps

Terminal window
APP_ID=$(alter apps create --name "ci-staging" --output json | jq -r '.id')
alter link "$APP_ID" # subsequent steps in this directory skip --app

Review and clean up archived apps

Terminal window
# List what's archived...
alter apps list --include-archived --output json \
| jq -r '.[] | select(.archived_at) | "\(.id)\t\(.name)"'
# ...then permanently delete one (name required as confirmation)
alter apps delete "$APP_ID" --confirm "ci-staging"

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.