For the complete documentation index, see llms.txt. This page is also available as Markdown.

App manifest (carto.json)

The carto.json file a hosted app ships to declare the Named Sources CARTO registers when it is deployed

Private Preview: Hosted Apps is available to selected accounts during its Private Preview. To request access, contact your CARTO representative.

carto.json declares the backend a hosted app needs: the connections it uses and the Named Sources it runs by name instead of sending SQL from the browser. CARTO reads it when you run carto app deploy, validates it, registers the Named Sources it declares, and keeps it to remove them when the app is deleted.

Where it lives

The manifest is a file named exactly carto.json at the root of the bundle directory you pass to carto app deploy. The CLI reads it and leaves it out of the upload, so it is never served and its SQL never reaches a browser. A carto.json in a subdirectory is treated as an ordinary file.

With Vite, place it in the public folder so that the build copies it to the root of dist.

The manifest is optional, and so is every field in it. An app that only reads tables the user already has access to needs no carto.json.

carto app schema prints this contract as JSON Schema, with every field described, and runs offline. Use carto app schema connection, source, migration or carto-info for one section, and --json for the compact form.

Top-level fields

Field
Type
Required
Constraints
Description

name

string

No

None

Informational. The app takes its name from carto app deploy --name, which defaults to the name of the bundle directory.

apis

array of string

No

At most 10 entries

The CARTO APIs the app uses: sql, maps, lds, imports, ai. Informational; see Declared APIs.

connections

array of connection

No

At most 20 entries

The connections the app declares Named Sources on.

Unknown top-level keys are ignored.

connections[]

Field
Type
Required
Constraints
Description

name

string

Yes

Non-empty

The name of a connection in your organization, or a handle you map at deploy time. See Connection handles.

provider

string

Yes

One of postgresql, bigquery, redshift, snowflake, databricks, oracle

The warehouse provider of the connection. Use bigquery for the CARTO Data Warehouse.

sources

object

No

At most 200 entries

Named Sources, keyed by a short name. See sources.

namespace

string

No

Matches /^[a-z_][a-z0-9_]*$/

Reserved. Accepted, but not used by the current release.

migrations

array of object

No

At most 200 entries

Reserved. Accepted, but not used by the current release.

A connection can also list tables and statements. They are only used by carto app check and carto app package to scope the token of a public build, and carto app deploy ignores them.

Connection handles

connections[].name can be the name of a connection in your organization, or a handle that you map to one at deploy time:

The flag is repeatable, and also accepts a comma-separated list (--connection a=c1,b=c2). A handle that is not mapped is used as a connection name.

Before registering the Named Sources of a connection, CARTO checks that the connection exists in your organization. If it does not, the deploy fails with No access to connection "<name>".

Named Sources are not tied to a connection: the app's code passes the real connection name (connectionName) each time it runs one.

sources

Each key in sources is the short name of one Named Source, and its sql is the parametrized query.

Field
Type
Required
Constraints
Description

sql

string

Yes

Non-empty, at most 100,000 characters

The SQL query. Use @param placeholders for the values the app sends with each request.

How they work:

  • The SQL is not sent to the browser. The app sends the name of the source and its parameters, and CARTO runs the stored query. See Avoid exposing SQL queries with Named Sources.

  • Each source is registered as <slug>_<key>. A source keyed stores_in_state in an app with the slug retail-stores is run as retail-stores_stores_in_state. The full name must follow the Named Sources naming rule, /^[a-z0-9][a-z0-9\-_]{2,50}(?<![-_])$/: 3 to 51 lowercase letters, digits, - and _, starting with a letter or a digit and not ending in - or _. The slug and the underscore count towards the 51 characters.

  • They are regular Named Sources, created by the user who deploys the app and listed in their Developers > Named Sources.

  • They run with the credentials of the user who opens the app, not those of the owner. A user without permission on the connection gets an error.

  • The SQL is run as written for the connection's warehouse. Besides SELECT, a source can be an INSERT, UPDATE or DELETE; the warehouse credentials the connection uses must then be allowed to write to the table.

Their lifecycle follows the app:

  • Each deploy creates or updates the sources listed in carto.json before it uploads the files. The version being served uses the new SQL from that moment, even if the deploy then fails.

  • A source you remove from carto.json is not deleted; remove it in Developers > Named Sources.

  • Deleting the app removes the sources listed in its latest carto.json.

  • A rollback does not change them. See Versions.

  • If a deploy fails, the sources it registered before the error remain. Fix the error and deploy again.

Declared APIs

apis records which CARTO APIs the app uses. It is informational: it is not a token scope and does not limit what the app can call. A hosted app always runs with the permissions of the signed-in user.

Complete example

Deployed with carto app deploy ./dist --slug retail-stores --connection warehouse=my_bigquery, this registers retail-stores_stores_in_state and retail-stores_store_set_revenue, which the app runs with connectionName: 'my_bigquery'.

Validation errors

The CLI validates the manifest before uploading anything, and CARTO validates it again when you deploy.

Message
Cause

Invalid carto.json: <message>

The file is not valid JSON.

carto.json: <path>: <message>

A field is invalid or a list is over its limit. <path> locates it, for example connections.0.provider.

No access to connection "<name>"

The connection does not exist in your organization. Check the name and any --connection mapping.

Invalid named source name "<slug>_<key>" (from key "<key>")

The full name breaks the naming rule above. Use a shorter key or slug.

Last updated

Was this helpful?