Skip to content

Astrato CLI reference

14 min read · Updated 2 Nov 2026

The astrato CLI develops Data Apps. It owns the local browser origin and proxies the project’s Vite server while delegating governed runtime operations to the real Astrato platform. It does not emulate Astrato services.

Preview: publication commands require an enabled Astrato environment and publication access. Publishing replaces the current app; deploy history, promotion and rollback are unavailable.

The CLI is not required for externally hosted apps or Workbooks.

During development, the CLI briefly reuses identity and semantic-layer metadata across charts under the same login. Queries still reach Astrato with your current credential. Reload the page after changing your semantic model to refresh metadata; you do not need to restart astrato dev.

Install @astrato-io/cli and @astrato-io/app-runtime from npmjs. Package installation is separate from astrato login, which authorizes the CLI to access Astrato.

The CLI requires Node.js >=24.18.0 <25 and installs one global executable:

Terminal window
npm install --global @astrato-io/cli
astrato --version

If astrato --version reports that the command is not found, npm’s global folder is not on your PATH. Run npm prefix --global to see the folder npm installs into:

  • Windows: add the folder that command prints (usually %APPDATA%\npm) to your user Path environment variable, then open a new terminal. In PowerShell, this adds it only if it is missing:

    Terminal window
    $prefix = npm prefix --global
    $userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
    $entries = @($userPath -split ';' | Where-Object { $_ })
    if ($entries -notcontains $prefix) {
    [Environment]::SetEnvironmentVariable('Path', (@($entries + $prefix) -join ';'), 'User')
    }
  • macOS and Linux: add the bin folder inside that prefix (for example, $(npm prefix --global)/bin) to PATH in your shell profile, then open a new terminal.

astrato login needs no environment variable. Run it once after installing. ASTRATO_TOKEN is only for automation; see Authentication.

The installed executable is the source of truth for its available commands and flags:

Terminal window
astrato --help
astrato help <command>
astrato <command> --help

The two command-specific help forms are equivalent.

-V, --version print the installed version
--json emit one machine-readable JSON result
--host <url> Astrato application host; defaults to https://app.astrato.io
-h, --help print help

Use --host only when your organization provides a different Astrato origin. Authentication is stored separately for each normalized host.

Command Needs login Needs configured semantic layer Supports --json Purpose
login [--force] No No No Complete interactive device authorization
logout No No Yes Revoke and remove the saved login
status No No Yes Report login and nearest local configuration
init [path] No Required input Yes Configure an existing Vite frontend
validate [path] No Yes Yes Validate config and project scripts
dev [path] [--no-open] Yes Yes No Run against the current semantic layer
build [path] No Yes Yes Build and validate a local static artifact
publish [path] Yes Yes Yes Build and replace an explicit publication
publications list/get Yes No Yes Find accessible publications and current versions
publications create [path] Yes Yes Yes Create an unpublished app
publications update/unpublish/delete Yes No Yes Manage an existing publication
semantic-layers visibility <id> Yes No Yes Show or set “Visible to everyone” for a layer

init, validate and build are local operations. They do not create a publication or check data access. Every supplied project path must be an existing, accessible directory.

Terminal window
astrato login
astrato login --force

The CLI opens the device-authorization page, prints the verification URL and user code, and waits for approval. Complete the approval in your browser. Access tokens remain in process memory, while the renewable login is stored in the operating system credential store. --force starts a new authorization even when a valid login already exists; use it only when you intentionally want to replace the saved login. If a saved grant lacks the scopes required by the installed CLI, status reports unauthenticated and login requests fresh approval.

The CLI requests profile schema:read data:query data:write data:sql publication:read publication:write publication:publish. Older logins without them need fresh approval through astrato login. Use the local write methods for App procedure execution and row changes during astrato dev. Arbitrary SQL is unavailable through the App runtime.

If access fails because scopes are missing, the CLI lists them and asks you to log in again. If Astrato rejects the scope request or returns an incomplete grant, ask your Astrato administrator to check the CLI client’s allowed scopes and your permissions before retrying.

login --json is rejected because login is interactive. An AI agent must not automate this flow or handle its device code. It should ask the user to run astrato login, wait for confirmation, then re-run astrato status --json.

Terminal window
astrato logout
astrato logout --json

Logout attempts server-side revocation and removes the saved credential. Do not run it merely to diagnose an error; it intentionally changes your saved authenticated state.

Terminal window
astrato status
astrato status --json

From inside a project, status discovers the nearest astrato.json and reports your login and local configuration. It does not check access to the semantic layer; dev performs that check. A representative JSON shape is:

{
"authentication": {
"issuer": "https://app.astrato.io",
"scope": "data:query profile schema:read",
"state": "authenticated"
},
"command": "status",
"project": {
"semanticLayerId": "296dddd1-c121-4f12-a4c2-3c735d327da2",
"configPath": "/absolute/project/astrato.json"
},
"ok": true
}

A directory without configuration returns "project":null. Do not parse the human-readable output in automation.

init configures an existing frontend project. The target must already be a directory containing package.json, a scripts object, and usable Vite development and build scripts.

Terminal window
astrato init [path] --semantic-layer-id <id>
astrato init [path]

Optional project overrides:

--dev-script <script> package.json script that starts Vite
--build-script <script> package.json script that builds the static frontend
--output <directory> build output relative to the project root

Without overrides, the CLI prefers dev and build scripts and otherwise infers scripts whose commands invoke Vite. It creates or validates astrato.json and ensures .astrato/ is in .gitignore. Re-running the same initialization is safe. It refuses to silently replace a different semantic-layer ID: changing that association requires an intentional config edit. If you rename scripts or change the output directory, re-run init with the corresponding overrides. Dev-script inference does not select vite preview, vite optimize or vite build.

A semantic-layer ID is required. In an interactive terminal, init prompts for it when omitted. Use an existing layer’s ID, not a name or an invented value. Initialization does not authenticate, create anything in Astrato, or verify access. Local development uses the model currently available to Astrato’s query engine, not an editor draft or a selected historical revision.

For non-interactive use, provide an absolute path, the semantic-layer ID and --json:

Terminal window
astrato init /absolute/project/path --semantic-layer-id <id> --json

Resolve the layer through live MCP context or ask the user. Do not publish or change the layer merely to make initialization succeed.

Terminal window
astrato validate [path]
astrato validate [path] --json

Validation searches from the supplied path toward the filesystem root for the nearest astrato.json, checks it against schema version 1, verifies the project scripts, and checks that the output directory stays safely inside the project. A canonical semantic-layer UUID is required. Validation is local and does not prove that your login can access that layer; dev checks access. Add --json for automation.

Terminal window
astrato dev [path]
astrato dev [path] --no-open

dev requires a saved login and configured semantic layer. It resolves the tenant and current semantic-layer metadata from Astrato, starts the configured Vite script, and exposes it through a per-run astrato-....localhost origin. The CLI prints and opens an HTTP sign-in URL that establishes your browser session and takes you to the clean App URL. Do not open Vite’s raw URL.

The CLI detects npm, pnpm, Yarn or Bun and forwards the loopback host, allocated port and strict-port options using that package manager’s argument syntax. You do not need to add these options to your development script.

Run separate astrato dev processes to develop multiple projects concurrently. Each gets its own framework port and App origin.

For both dev and build, install your package manager and make it available on PATH. On Windows, the CLI resolves it to an absolute file using the project’s working directory, PATH and executable extensions in PATHEXT. Native executables run directly; .cmd and .bat shims run through cmd.exe with quoted paths and validated arguments. Installation paths may contain spaces or ampersands. Batch-shim paths containing %, ! or double quotes are rejected; use an installation path without those characters. On macOS and Linux, the manager runs directly.

astrato dev 0.1.1 or later, with @astrato-io/app-runtime 0.2.0 or later, runs App procedure calls and row writes. Published Apps reject them.

Use the App runtime write methods without adding permission lists to astrato.json. The CLI binds procedures to the configured layer’s datasource and checks row views and fields against its current model. Your Astrato permissions, OAuth scopes and warehouse permissions govern execution. Procedure and schema names use unquoted identifiers, with an optional database prefix in the schema. Arbitrary SQL remains unavailable through the App runtime.

Semantic Business Workflow definitions are authoring and preparation metadata. The CLI does not expose their registry, execute them by name or look up their execution status. Existing explicit procedure and table-write APIs do not apply those definitions.

Queries use the model currently available to Astrato’s query engine. After changing that model, reload the page to fetch its current field metadata. The CLI does not pin a model revision or notify you when it changes, so an already-open page can temporarily have older metadata than its queries.

The browser receives a Data App session scoped to this dev run and can reach only the versioned /_astrato/v1/* runtime boundary. The authored Data App never receives the CLI’s OAuth token. The gateway exits with the frontend process and stops both on Ctrl+C. Allow a few seconds for cleanup; repeated Ctrl+C does not skip it.

Use --no-open to open the printed sign-in URL in your chosen browser instead of automatically launching the default browser. Reuse the same link in any browser profile on the same computer while this dev process runs. It has no short expiry or single-use restriction. Clearing browser cookies or switching browsers does not require a new link or a restart.

The URL grants access only to the running local app and contains no Astrato OAuth token or PAT. Avoid sharing it: anyone with the link and access to the local gateway can establish a session until the process stops. Shutdown invalidates the link and all its browser sessions; a restarted process prints a new link. Remote browsing and port forwarding are not supported. dev is long-running and does not support --json.

Browser automation does not require --no-open. Choose the opening mode for the browser you intend to use; see Browser automation for browser preferences, profile-specific admission and manual fallbacks. Agents may use the printed sign-in URL with a local browser tool; this does not authorize automating account login or handling OAuth credentials.

Terminal window
astrato build [path]
astrato build [path] --json

The CLI detects the project’s package manager, runs <manager> run <configured-script>, replaces only the validated configured output directory, and checks the resulting static artifact. Success writes .astrato/build-manifest.v1.json containing sorted relative paths, media types, byte counts, per-file SHA-256 values and one deterministic artifact digest.

The artifact must contain a root index.html. It may contain at most 10,000 files, 250 MiB total, 50 MiB per file and 1,024 bytes per relative path. Symbolic links, unsupported file types, source maps, service-worker registration, project files, credential files and detected concrete secret or private-key material are rejected.

build --json suppresses the frontend build logs so stdout contains one result. Building does not upload or deploy the artifact.

astrato init owns this file. Do not hand-write it when the CLI is available. The current generated shape is:

{
"$schema": "https://schemas.astrato.invalid/hosted-app/v1/astrato.schema.json",
"semanticLayerId": "296dddd1-c121-4f12-a4c2-3c735d327da2",
"build": {
"output": "dist",
"script": "build"
},
"dev": {
"adapter": "vite",
"script": "dev"
},
"hosting": {
"spa": true
},
"kind": "app",
"schemaVersion": 1
}

The .invalid schema host is an intentional preview placeholder and is not expected to resolve. schemaVersion, not $schema, selects the contract enforced by the CLI.

Property Meaning
$schema Editor hint written by the CLI; it does not select CLI behavior
schemaVersion Configuration contract version; currently exactly 1
kind Project kind; currently exactly "app"
semanticLayerId Required semantic-layer UUID; local development uses its current engine model
dev.adapter Local framework adapter; currently exactly "vite"
dev.script Name of the package.json script that starts Vite
build.script Name of the package.json script that produces static output
build.output Project-relative static output directory; must not escape or overlap protected directories
hosting.spa Whether hosting should use single-page-application fallback; currently generated as true

Do not add credentials, tenant IDs, datasource IDs, revision pins, environment targets or API origins to this file. Only the semantic-layer ID belongs in config; Astrato resolves and authorizes the remaining context using your current login.

Use --json for agents and automation except where explicitly unsupported. A successful command writes exactly one JSON object to stdout and exits 0:

{
"command": "validate",
"configPath": "/absolute/project/astrato.json",
"semanticLayerId": "296dddd1-c121-4f12-a4c2-3c735d327da2",
"ok": true
}

A failed command writes exactly one JSON object to stderr:

{
"error": {
"code": "config_invalid",
"message": "astrato.json does not match the Data App v1 schema.",
"details": {}
},
"ok": false
}

Exit codes are:

  • 0 — success;
  • 1 — unexpected/internal failure;
  • 2 — expected request, configuration, authorization, network, runtime or artifact failure;
  • 3 — operating system credential-store unavailable or corrupt.
  • 130 — cancelled by an interrupt, including an interactive prompt.

Treat error.code as the stable programmatic category. Display error.message and retain details for diagnosis; do not parse prose to decide the next action.

A missing saved login is unauthenticated. If reading or deleting a credential fails because the store is locked or access is denied, the CLI reports credential_store_unavailable with exit code 3. A failed deletion does not report a successful logout. Restore access to the operating system credential store and retry; the CLI has no plaintext credential fallback.

If another CLI process holds the credential lock, let it finish or close it and retry. A crashed process can leave an incomplete lock; only remove the specific lock reported in the error after confirming no other CLI process is using that login. Do not delete the whole private directory or clear your credential store to diagnose a lock error.

If dev reports upstream_invalid_response while resolving your data context, the message identifies whether account, semantic-layer or datasource metadata failed validation. Share that message when reporting the problem; do not share credentials or raw API response contents.

  • Confirm that the project is a Data App before using this CLI.
  • If astrato is missing, follow the supported global installation above. If installation is not permitted or package access is unavailable, tell the user exactly what is missing; do not switch hosting models.
  • Prefer absolute project paths, explicit init choices and --json.
  • Ask the user to perform astrato login personally; never request or handle authentication material.
  • Use init for supported config updates. Never invent IDs, open Vite’s raw origin, or emulate the local gateway.
  • Publish only when authorized, using the documented commands below; do not manufacture deployment commands.

Use the current CLI preview containing these commands (astrato publish --help). Your administrator must enable publications on your Astrato host. Management commands use your saved astrato login by default and check your normal publication permissions. Log in again if your existing grant predates publication authoring support. The semantic layer must already be published and its connection must select a supported exit node. Use the App runtime for hosted queries; do not upload code that depends on a local development query proxy.

For interactive use, run astrato login, then use the publication commands below. For automation, you can override the saved login with exactly one explicit credential. For a PAT, follow the secure PAT input example to set ASTRATO_TOKEN. Alternatively, supply your browser session’s Cookie header as ASTRATO_COOKIE using hidden input:

Terminal window
printf 'Astrato session cookie: '
IFS= read -r -s ASTRATO_COOKIE
printf '\n'
export ASTRATO_COOKIE

Do not set both variables or put credential values in command arguments, project files or chat. The CLI never reads browser credential stores. The CLI handles CSRF for cookie credentials; PAT calls use bearer authentication. Unset the variable when finished. Explicit credentials take precedence; a rejected PAT or cookie does not fall back to OAuth. Publication tokens are not passed to customer build subprocesses or command results.

Terminal window
astrato publications create ./my-app --name "Sales app" --idempotency-key sales-app-create-1
astrato publications get <publication-id>
astrato publish ./my-app --publication-id <publication-id> --expected-version <version> --idempotency-key sales-app-publish-1

create reserves an unpublished target; it does not build, upload or publish app content. Use the ID returned by create and the version returned by get. There is no implicit publication target saved in astrato.json. Pass --host with the Astrato origin you logged into or that issued your explicit credential when your organization uses a different origin. You need create permission to create a publication, and publish permission plus semantic-layer access to upload it.

publish first checks publication access, OAuth publish scope, the published semantic layer and selected hosting location without changing the publication. Failed prerequisites stop before the build; use publications get <publication-id> --hosting --json to inspect available locations and data-node warnings. This check does not probe storage, the hosted app or data queries. The server rechecks prerequisites when preparing and completing the upload.

The command then runs the configured build, uploads each validated file and asks Astrato to verify the contents before making them current. OAuth tokens, PATs and session cookies are never uploaded with the files. New files use your tenant’s existing storage; you do not configure a bucket. CLI builds permit up to 50 MiB per file and 250 MiB in total; publishing additionally limits the artifact to 2,000 files. A failed upload leaves the previously published app available.

For automation, add --json to receive one result containing publication metadata, without upload URLs or credentials. The result’s verification distinguishes verified artifacts from unchecked application loading and data queries. Open the hosted app to verify those separately. When no canonical URL is available, publication.urlUnavailableReason explains why; a missing configured hostname requires administrator action. login remains interactive and does not support JSON mode.

Terminal window
astrato publications list
astrato publications list --cursor <next-cursor> --json
astrato publications get <publication-id> --json
astrato publications update <publication-id> --name "Sales dashboard" --expected-version <version>
astrato publications update <publication-id> --audience public --expected-version <version>
astrato publications unpublish <publication-id> --expected-version <version> --yes
astrato publications delete <publication-id> --expected-version <version> --yes

List returns at most 100 items; follow nextCursor until it is null. Unpublish disables delivery and allows later republishing. Delete removes the publication from the catalog and disables its URL; it cannot be undone through the CLI. Audit records and stored files are retained. Deletion requires its own delete permission. Use Publications → Manage Access in the lobby to edit permissions.

--audience public makes an app open without sign-in. It needs manage-access permission on the publication and the workspace’s external embedding setting, as in the lobby.

Terminal window
astrato semantic-layers visibility <semantic-layer-id>
astrato semantic-layers visibility <semantic-layer-id> --everyone true
astrato semantic-layers visibility <semantic-layer-id> --everyone false --json

Without --everyone the command reports whether the layer is visible to everyone in the workspace. --everyone true and --everyone false set the editor’s Visible to everyone toggle; grants to named users, groups and roles are kept. Astrato checks that you may manage access to the layer. Use a PAT (ASTRATO_TOKEN) or astrato login; a browser cookie session is not accepted here.

Retry the same command with the same idempotency key, expected version and unchanged build output. Astrato resumes the interrupted upload. A successful completed attempt can also be retried safely. If rebuilding produces different content, read the latest publication and start a new operation with a new key. Never reuse a key for different content, and never automatically overwrite a version_conflict. Read current state and decide which change to keep.

The saved OAuth login renews access automatically. If the login is revoked or lacks scopes, run astrato login again. For an explicit PAT or cookie, replace that credential instead. A permission error requires the appropriate publication ACL; supplying a different authentication method does not grant additional rights.