Custom Apps
Custom apps are full Vite/React/TypeScript projects hosted by Autessa. The CLI can pull an app's draft source to your machine, push edits back, and run a production deploy — which makes an Autessa app editable with whatever editor, diff tool, or coding agent you already use.
Key concepts
Draft and published
An app has a draft — the private working copy — and a published version, which is what end users actually reach. push writes to the draft. Nothing you push is live.
Publishing is a production deploy, not a save. It snapshots the draft, builds it, and once the build succeeds serves it to everyone with access — its public URL and any custom domains — replacing whatever was live before. Treat it as a deliberate step, not a reflex after every edit.
What the file API covers
pull and push handle text source files only. The read-only src/autessa/ library — the generated bindings an app uses to reach agents, tools and tables — is never returned by pull and cannot be pushed.
index.html is Vite's entry shell: a <div id="root"> and a module script tag. Page content belongs in the React files under src/. Overwriting index.html with static markup breaks the app.
autessa.config.json
Every app carries a config file binding it to the platform resources it uses:
{
"version": "1.0.0",
"agents": { "TODO_MANAGER": "Lo59cuYy9d8T" },
"tools": {},
"tables": {
"TODO_LIST": "U49RQBUdAaRq",
"TODO_COMMENTS": "mcjl7XmDfKCI"
},
"managers": {},
"scheduledJobs": {}
}
This is the seam between an app and everything else you build headless. A script that creates a table and an agent can write their ids straight into this file and push it, and the app picks them up.
How to find an app
autessa app all --output table
appId appName sharingLevel userAccessLevel hostingMode latestVersion publishedVersion
------------ ----------- ------------ --------------- ----------- ------------- ----------------
GTBhswTJ6a9r BasicTodo PRIVATE ADMIN DEFAULT 1 1
lCHdKACw4tpE BasicTodo PRIVATE ADMIN DEFAULT
An app with no publishedVersion has never been deployed — it exists only as a draft.
Get the URLs a human needs:
autessa app visible-urls --appId GTBhswTJ6a9r
{
"editorUrl": "https://builder.autessa.com/app-builder/editor/GTBhswTJ6a9r",
"publishedUrl": "https://builder.autessa.com/customappsv2/view/GTBhswTJ6a9r"
}
autessa app get returns full details plus the draft file listing; get-app-info is a lighter read that skips the file listing.
How to pull the source
autessa app pull --appId GTBhswTJ6a9r
Returns a path→content map of the draft's editable files:
{
"files": {
"autessa.config.json": "{\n \"version\": \"1.0.0\", ... }",
"index.html": "<!DOCTYPE html>\n<html lang=\"en\"> ... ",
"package.json": "{\"private\":true,\"devDependencies\":{ ... }}",
"src/App.tsx": "...",
"src/components/ui/Button.tsx": "...",
"src/pages/Todos.tsx": "..."
}
}
Paging
Large apps come back in pages. When nextPageToken is present, call pull again with it until it is absent:
autessa app pull --appId GTBhswTJ6a9r --pageToken <token>
A file larger than the transfer budget is reported in skipped rather than dropped silently — check that array, don't assume an empty response means an empty app.
Writing the files to disk
pull returns JSON, so unpacking it is one jq step:
mkdir -p ./myapp && cd ./myapp
autessa app pull --appId GTBhswTJ6a9r \
| jq -r '.files | to_entries[] | @base64' \
| while read -r row; do
entry=$(echo "$row" | base64 --decode)
path=$(echo "$entry" | jq -r '.key')
mkdir -p "$(dirname "$path")"
echo "$entry" | jq -r '.value' > "$path"
done
Now edit with anything — your editor, a formatter, a coding agent, a codemod.
How to push edits back
push takes the same path→content map:
autessa app push --appId GTBhswTJ6a9r --files '{
"src/pages/Todos.tsx": "import React from \"react\";\n\nexport default function Todos() {\n return <div>…</div>;\n}\n"
}'
{
"savedPaths": ["src/pages/Todos.tsx"],
"deletedPaths": []
}
Rebuild the map from a local directory:
FILES=$(find . -type f \
! -path './node_modules/*' ! -path './.git/*' ! -path './dist/*' ! -path './src/autessa/*' \
-print0 | xargs -0 jq -Rs 'input_filename as $f | {($f | ltrimstr("./")): .}' | jq -s 'add')
autessa app push --appId GTBhswTJ6a9r --files "$FILES"
Skip node_modules, .git, dist/build, lockfiles, src/autessa/, and any binary files — the file API is text-only.
Mirroring vs. adding
By default push mirrors: draft files absent from your payload are deleted, so a partial push removes everything you left out. That is what you want when pushing a complete local tree.
--addOnly changes it to add-and-update, never delete:
autessa app push --appId GTBhswTJ6a9r --files '{"src/pages/Todos.tsx":"..."}' --addOnly
Use --addOnly for a targeted single-file edit. Use the default mirror when your local directory is the authoritative copy.
The response tells you exactly what happened — savedPaths, deletedPaths, and binaryContentPaths for anything containing NUL bytes (still saved, but worth a look).
How to publish
Only when the app is genuinely meant to go live:
autessa app publish --appId GTBhswTJ6a9r
Publishing is asynchronous. It returns a publishJobId and a version and starts a build; the app is live only once that build reaches SUCCESS:
autessa app publish-status --publishJobId <id>
Poll while terminal is false, and watch phase. A FAILED build carries the error tail — fix the draft and publish again.
You can also publish as part of a push:
autessa app push --appId GTBhswTJ6a9r --files "$FILES" --publish
which returns version, buildId, publishJobId and buildStatus: BUILDING — still asynchronous, still needing publish-status.
publish returning cleanly means the build started.How to create, clone and roll back
# start from a template
autessa app create --appName "My Site" --templateType SAAS_APP
# copy an existing app's draft into a new private app you own
autessa app clone --appId GTBhswTJ6a9r --appName "My Site (fork)"
# roll the DRAFT back to a previously published version's source
autessa app rollback --appId GTBhswTJ6a9r --version 1
# list versions with build status
autessa app versions --appId GTBhswTJ6a9r
Templates are BOOTSTRAP, SAAS_APP, LANDING_PAGE and DASHBOARD. Note what rollback does: it restores the draft from an old version's source. It does not itself change what is live — publish afterwards for that.
How to control access and domains
autessa app get-sharing-details --appId GTBhswTJ6a9r
autessa app share --appId GTBhswTJ6a9r \
--sharingLevel COMPANY \
--companyPermissionLevel WRITE \
--hostingMode AUTH_CODE \
--publicSlug my-site \
--authCode s3cr3t
share configures two independent things in one ADMIN-only call: who can edit the source (code sharing), and how end users reach the deployed app (hosting mode). get-sharing-details is the read-only view of exactly what it would modify.
Custom domains:
autessa app check-slug --appId GTBhswTJ6a9r --publicSlug my-site
autessa app domains add --appId GTBhswTJ6a9r --domainName app.example.com
autessa app domains status --appId GTBhswTJ6a9r
autessa app domains verify --appId GTBhswTJ6a9r --domainId <domainId>
autessa app domains remove --appId GTBhswTJ6a9r --domainId <domainId>
domains add returns the CNAME — and, when required, the TXT verification record — the domain owner must create. domains status lists each domain's state, its CNAME target, the live URL once ACTIVE, and the TXT record while PENDING_TXT. domains verify runs one provisioning step synchronously instead of waiting for the next scheduled poll, and also resets a FAILED domain for retry.
What stays in the web builder
The visual app builder — the workspace, the file tree UI, and the vibecode assistant — is a browser experience. The CLI covers the file round-trip and the lifecycle; it does not replace the editor. See App Builder and Vibecode.
Full command reference
| Command | What it does |
|---|---|
| autessa app all | List every custom app you can access in the current company, each with its latest/published version numbers, hosting mode, slug, and your access level. |
| autessa app check-slug | Check whether a public URL slug is available and validly formatted, returning available and a reason. |
| autessa app clone | Create a new private app you own by copying another app's draft source files. |
| autessa app create | Create a new custom web app from a starter template, scaffolding its draft files. |
| autessa app delete | Permanently delete an app — its custom domains, all draft/version/build files, and database rows. |
| autessa app domains add | Attach a customer-owned custom domain to an app and get back the CNAME (and possibly TXT verification) records the domain owner must create. |
| autessa app domains remove | Detach a custom domain from an app and tear down its CDN tenant. |
| autessa app domains status | List an app's custom domains with status, CNAME target, live URL when ACTIVE, and the TXT verification record when PENDING_TXT. |
| autessa app domains verify | Synchronously run one step of domain provisioning (DNS check, tenant creation, certificate attach) instead of waiting for the next scheduled poll; also resets a FAILED domain for retry. |
| autessa app get | Fetch one app's full details (versions, hosting mode, slug, public URL, your access level) plus its draft file listing. |
| autessa app get-app-info | Fetch just an app's details (name, versions, hosting mode, slug, public URL, your access level) — a lighter read than get that does not return the draft file listing or refresh the library files. |
| autessa app get-sharing-details | Get an app's sharing level, company permission, hosting mode, per-user grants, and your own access level — a read-only view of exactly what share would modify. |
| autessa app preview-url | Web appApp preview URLs are opened from the app builder in the web app. |
| autessa app publish | Publish the app — a PRODUCTION DEPLOY of all your draft changes, not a save. |
| autessa app publish-status | Poll the live progress of a publish job (from publish) until it finishes. |
| autessa app pull | Download an app's editable draft source files to sync a draft to a local folder, one page at a time. |
| autessa app push | Save files into an app's draft — the private working copy, one step below deploying to production. |
| autessa app rollback | Roll the app's editable DRAFT back to a previously published version's source. |
| autessa app share | Configure two independent things about an app in one ADMIN-only call: who can EDIT its source (code sharing) and how END-USERS reach the deployed app (hosting). |
| autessa app update | Update an app's metadata — appName, description, and the public SEO fields. |
| autessa app versions | List all versions of an app, newest first, with each version's state, buildId, and live build status. |
| autessa app visible-urls | The two URLs that matter for an app, composed in one call: editorUrl, where the owner opens it in the builder, and publishedUrl, the single live URL its end-users reach. |