Skip to main content

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.

npx create-terse brings up a full Terse control plane (backend, dashboard, Postgres) as Docker containers on a machine you operate. By default the data plane runs locally too; flip to a remote runtime later if you need to. If you only want job code to run in your network and would rather keep Terse Cloud managing triggers and history, see Self-hosting the data plane. For the bigger picture, see Hosting overview.
Self-hosted Terse is governed by the Sustainable Use License. Internal business use is fine. Reselling it as a hosted product is not.

Bootstrap

npx create-terse
You’ll be prompted for a target directory (default ./terse) and the frontend and backend URLs the instance should serve on. The script writes docker-compose.yml, .env, and a README.md into the directory, generates secrets, pulls the Terse image, and runs docker compose up -d. Migrations run inside the backend container on startup. If terse-cli isn’t on PATH, it’s installed globally and pointed at your new instance. Prerequisites: Docker with Compose v2, and Node 20+ for npx. No repo clone, no pnpm, no manual Prisma steps.

Non-interactive mode

For CI, scripts, or AI agents (Claude Code, etc.) that can’t answer prompts, pass -y to accept all defaults. The script also auto-enables this mode whenever stdin or stdout is not a TTY, so it won’t hang in a non-interactive shell.
npx create-terse -y                                                              # all defaults
npx create-terse -y --target ./my-terse                                          # override target dir
npx create-terse -y --backend-url http://localhost:3001 \
                    --frontend-url http://localhost:5173                          # override URLs
FlagDefaultPurpose
-y, --non-interactiveoffSkip prompts and accept defaults. Auto-on when no TTY.
--target <dir>./terseInstall directory.
--frontend-url <url>http://localhost:5173Frontend URL written to .env.
--backend-url <url>http://localhost:3001Backend URL written to .env.
The CLI target is exported into your shell rc. Run source ~/.zshrc or open a new terminal before your next terse command, otherwise the CLI still points at Terse Cloud. Confirm with terse target.

First login

With no WORKOS_* env vars set, the backend runs in single-operator mode. The first request bootstraps an admin identity and hands you a session cookie. There is no signup form and no second user. Anyone who can reach the backend URL becomes the admin. For real multi-user auth, add the WORKOS_* env vars to .env and restart. The backend swaps in WorkOS on next boot.
Before exposing the instance off localhost, put it behind an authenticated proxy (Tailscale, Cloudflare Access, basic auth, whatever fits your stack) and set NODE_ENV=production in .env so session cookies are marked secure.

Where job code runs

terse deploy against a self-hosted instance runs jobs as subprocesses inside the backend container, without per-run isolation. That’s fine for code you wrote and trust. To run jobs in isolated per-execution sandboxes (what Terse Cloud uses), set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET in .env and restart. To run them in your own runtime instead (a worker fleet, an internal Kubernetes cluster), use the Hybrid setup.

Configuration

Anything user-tunable lives in .env. Edit and run docker compose up -d to apply. The bootstrap fills in sensible defaults; the variables you’ll actually touch are:
VariablePurpose
FRONTEND_URL, BACKEND_URLWhat the browser sees. Change both together if you put the instance behind a real domain.
LOCAL_SECRETS_ENCRYPTION_KEYEncrypts project secrets at rest. Generated for you. Back it up out of band — lose it and every stored integration credential is unrecoverable.
NODE_ENVdevelopment by default. Set to production before exposing the instance.
TERSE_IMAGEPin to a specific image tag instead of :latest. Commented out by default.
WORKOS_*, MODAL_*, RESEND_API_KEY, integration OAuth secretsOpt in to anything that’s off by default.
Anything else (container-internal URLs, port mappings, volume names) lives in docker-compose.yml. The README.md in your install directory is the daily-ops cheat sheet for logs, upgrades, and backups.

Integrations

There is one config file, .env. Adding integration credentials there and running docker compose up -d enables the integration on the next restart. No per-integration config file, no second admin panel. API-key integrations (Datadog, Snowflake, HeyReach, LaunchDarkly, PostHog) need no env vars. Connect them from the dashboard, paste the API key, done. OAuth integrations are gated by env vars. Every required var below must be set and non-empty, otherwise the integration is hidden from the dashboard’s connect list:
IntegrationRequiredOptional
GmailGMAIL_CLIENT_ID, GMAIL_CLIENT_SECRET, GMAIL_REDIRECT_URI, GMAIL_FRONTEND_REDIRECT, GMAIL_PUBSUB_TOPICGMAIL_PUBSUB_AUDIENCE, GMAIL_PUBSUB_SERVICE_ACCOUNT_EMAIL
GitHubGITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_APP_CALLBACK_URL, GITHUB_APP_NAMEGITHUB_LOGIN_CALLBACK_URL, GITHUB_LOGIN_REDIRECT
SlackSLACK_CLIENT_ID, SLACK_CLIENT_SECRET, SLACK_OAUTH_CALLBACK_URLSLACK_SIGNING_SECRET
LinearLINEAR_CLIENT_ID, LINEAR_CLIENT_SECRET_ID, LINEAR_OAUTH_CALLBACK_URL, LINEAR_WEBHOOK_SIGNING_SECRET
NotionNOTION_OAUTH_CLIENT_ID, NOTION_OAUTH_CLIENT_SECRET, NOTION_OAUTH_REDIRECT_URI
AttioATTIO_CLIENT_ID, ATTIO_CLIENT_SECRET, ATTIO_REDIRECT_URI
Web monitors (Parallel)PARALLEL_API_KEY, PARALLEL_WEBHOOK_SECRET
Callback URLs must be reachable from the browser. For a default local install: http://localhost:3001/<provider>/callback on the backend side, http://localhost:5173/ (or your FRONTEND_URL) on the frontend side. If the OAuth provider rejects localhost (Google does for several Gmail scopes, Slack does for distributed apps), expose the backend through a tunnel (ngrok, Cloudflare Tunnel) and point the callback URLs at the public hostname.

Where to go next

Hosting overview

Compare the three deployment options.

Hybrid: self-host the data plane

Keep Terse Cloud for orchestration, run jobs in your VPC.

CLI reference

Every terse command, including terse target for retargeting.

Quickstart

Build your first workflow against the running instance.