app
Publish a built frontend as a CARTO-hosted app, or prepare a public build of one you host yourself. A hosted app is a static bundle served at <workspace-url>/app/<slug>/ behind your organization login; it runs as the signed-in viewer and calls the CARTO API directly. Hosting your application in CARTO walks through building one, and the Hosted Apps reference describes the manifest and the runtime contract; this page is the command reference.
When Hosted Apps is not enabled for your account, carto app deploy exits 1 and explains how to request access (--json adds "code": "hosted-apps-feature-disabled"). The other commands keep working, so apps already deployed can still be shared, rolled back or deleted. On a CARTO deployment that predates Hosted Apps, the commands that manage hosted apps fail the same way.
The bundle and carto.json
The directory you deploy or package is a built static bundle: index.html at the root, at most 1000 files, 25 MB per file and 50 MB in total. At runtime the app fetches ./carto-info.json (relative to its own path) to get the viewer's access token and the CARTO API base URL.
An optional carto.json at the bundle root declares the backend the app needs: the connections it reads from and the named sources (parametrized SQL) it invokes by name. It is read at deploy or package time and never served. Connections may also list tables and statements; they only scope the public token when packaging, and carto app deploy strips them. carto app schema prints the full reference for both files; App manifest documents carto.json field by field.
carto app deploy <directory>
Package and upload a bundle, provision the backend declared in carto.json, and serve the new version.
carto app deploy ./dist --name "Store Explorer"
carto app deploy ./dist --slug store-explorer --connection warehouse=my_bigquery
carto app deploy ./dist --jsonOptions:
--name <name>
Display name (default: directory basename).
--slug <slug>
URL slug: lowercase, digits, hyphens (default: slugified name).
--version <label>
Version label, unique per deploy (default: UTC timestamp).
--description <text>
Optional description.
--connection handle=name
Map a carto.json connection handle to a real connection. Repeatable.
carto app list
List the hosted apps available to you.
carto app versions <slug>
List an app's deployed versions and which one is active.
carto app rollback <slug> [version]
Serve an already-deployed version. Only the bundle changes; the provisioned backend is untouched.
carto app share <slug>
Choose who can open the app: only you, everyone in the organization, or specific groups and users (by id).
Options:
--private
Only you can open it.
--org
Everyone in your organization.
--group <ids>
Share with specific groups (comma-separated).
--user <ids>
Share with specific users (comma-separated).
carto app delete <slug>
Delete the app: every deployed version and the named sources it registered. Asks for confirmation unless --yes is passed.
carto app schema [section]
Print the JSON Schema for carto.json (the deploy manifest) and carto-info.json (the runtime bootstrap), with every field described. Runs offline.
Sections: manifest (default), connection, source, migration, carto-info.
carto app check <directory>
Safety report before a bundle goes public. Runs offline. It derives the grants a public token would need from carto.json (tables, exact statements, named sources), blocks DDL, multi-statement SQL and line comments, flags writes wherever they appear in a statement, and scans every non-binary file for .env files, known secret shapes (JWTs, private keys, cloud and Git host keys) and a stray carto-info.json. Exit code 1 when something blocks.
Options:
--slug <slug>
Slug used to name registered sources (default: slugified directory name).
--name <name>
Display name the slug is derived from.
--connection handle=name
Map a carto.json connection handle to a real connection. Repeatable.
--allow-writes
Accept INSERT / UPDATE / DELETE grants; otherwise they block.
carto app package <directory>
Build a public version of a bundle you host yourself. It runs the check, registers the manifest's named sources, mints one least-privilege API Access Token named app:<slug>@<timestamp>-<nonce> locked to the referer in --url (path included when the URL has one), verifies the token by replaying the allowed calls and probing a forbidden one, revokes earlier app:<slug> tokens so re-runs are idempotent, and writes <out>/carto-info.json next to a copy of the bundle. The package is recorded in .carto/packages.json. The token is masked on stdout unless --show-token is passed; it is always written to carto-info.json.
Read-only tokens expire in one year, tokens with write grants in 30 days; --expires changes either.
Options:
--out <dir>
Output folder (default: <directory>-public).
--url <public-url>
Where the app will be hosted; locks the token to that referer.
--slug <slug>
Slug used to name registered sources and the token (default: slugified name).
--name <name>
Display name (default: directory basename).
--connection handle=name
Map a carto.json connection handle to a real connection. Repeatable.
--allow-writes
Grant INSERT / UPDATE / DELETE statements; the token then expires in 30 days unless --expires says otherwise.
--expires <when>
Token expiry: an ISO date, 1d / 2w / 6m / 1y, or never (read-only tokens only). Default: 1y, or 30d with writes.
--dry-run
Run the check and show the plan; mint and write nothing.
--skip-verify
Skip replaying the grants against the new token.
--show-token
Print the full token instead of masking it.
--update-referer <url>
Rotate the recorded token so it is restricted to this public URL.
deploy publishes an internal app (organization login, viewer token). package produces a public one (scoped API Access Token, hosted by you).
Last updated
Was this helpful?
