Terse splits into two planes. You can pick where each one runs independently.Documentation Index
Fetch the complete documentation index at: https://docs.useterse.ai/llms.txt
Use this file to discover all available pages before exploring further.
| Plane | What it does | Where it can run |
|---|---|---|
| Control plane | The orchestrator. Ingests triggers, stores config, schedules runs, holds run history, serves the dashboard. | Terse Cloud (default) or self-hosted |
| Data plane | The runtime that executes your onTrigger code, agent runs, and tool calls. | Terse Cloud sandboxes or self-hosted |
The three deployments
Most users land on one of these:Managed
Terse Cloud runs both planes. Default after
terse init. Nothing to operate.Hybrid
Terse Cloud runs the control plane. Your infrastructure runs the data plane. Useful for private data and VPC-only services.
Self-hosted
You run both planes inside your network. Bootstrapped with
npx create-terse.A fourth combination (self-hosted control plane plus Terse Cloud data plane) is technically valid but uncommon. If you’ve gone to the trouble of running the control plane yourself, you almost always want the data plane local too.
Managed
The default when you scaffold a project withterse init. terse deploy zips your code, uploads it, registers every job’s triggers on the control plane, and from then on each run lands on an isolated Modal sandbox in the Terse Cloud data plane, provisioned per execution.
Security
Each execution runs in its own Modal sandbox with a project-scoped, short-lived API token that is removed when the run finishes. Code and credentials are never shared across runs or organizations.Secrets
Secrets are project-scoped and write-only.terse secrets add OPENAI_API_KEY (or terse secrets import .env for a whole file) encrypts the value and injects it into that project’s sandbox as an environment variable at run time. Other projects in your org can’t see it, and once stored the value can’t be read back out by anyone — including the CLI and any AI coding agent you point at the project. A leaked API key or a compromised laptop never exposes the rest of your secrets. See Projects for how project scope works across deploys, jobs, and integrations.
The tradeoff: terse test can’t pull hosted secrets onto your machine for local runs. Keep a gitignored .env in your project directory with the same variable names — the CLI loads it automatically for terse test, and the deploy step excludes it from the upload, so the sandbox always uses what you stored with terse secrets.
terse secrets add <NAME> overwrites a value, terse secrets remove <NAME> deletes it, and terse secrets list shows which names are set on the server. The values themselves stay sealed.
What gets uploaded
The CLI respects standard ignore patterns. The following are always excluded:- TypeScript
node_modules, .git, dist, .next, .turbo, .env, .DS_StoreHybrid: self-host the data plane
Keep Terse Cloud as the control plane but run youronTrigger handlers in your own infrastructure. Useful when jobs need access to private data, VPC-only services, or credentials managed in your environment. See Self-hosting the data plane for the setup.
Self-hosted: both planes
Run the control plane and data plane entirely inside your network. Triggers, dashboard, run history, and execution all live in your environment. See Self-hosting the control plane for thenpx create-terse bootstrap and operational guidance.