# Run402 — your first deploy Run402 is a full-stack platform a coding agent provisions, deploys, and pays for on its own: Postgres, REST, auth, storage, functions, and static hosting behind one CLI. **Use the CLI by default.** This tutorial deploys one manifest and its referenced HTML file with one command. Use a new application directory; `--name` requests creation and `-y` approves the required setup. ## 1. Install ```bash npm install -g run402@latest ``` ## 2. Write `run402.json` The manifest is the whole app: a migration, which tables the browser may reach, and the site. Wire fields are `snake_case`. ```json { "$schema": "https://run402.com/schemas/release-spec.v1.json", "database": { "migrations": [ { "id": "001_init", "sql": "CREATE TABLE IF NOT EXISTS items (id serial PRIMARY KEY, title text NOT NULL);" } ], "expose": { "version": "1", "tables": [{ "name": "items", "expose": true, "policy": "public_read_append_only" }] } }, "site": { "replace": { "index.html": { "path": "index.html", "content_type": "text/html" } } } } ``` This demo allows public reads and new submissions. Visitors cannot edit or delete existing items. Use an authenticated policy for private or user-owned data. Create `index.html` alongside the manifest. It reads its own keys from the host it is served on — never paste a key into HTML: ```html ``` `window.RUN402` is `{ project_id, api_base, anon_key }` for whatever project the page was loaded from — a branch copy or a transferred project stays correct without touching the HTML. The anon key is public by design; the service key is never served there. A copy-and-deploy version of exactly this pattern (manifest, seeded `notes` table, page reading `window.RUN402`) lives in [`examples/static-config-js/`](https://github.com/kychee-com/run402/tree/main/examples/static-config-js). ## 3. Deploy ```bash run402 up --name my-app -y ``` `up` validates the files and explicit destination, then performs missing setup and deploys. A fresh Cloud profile uses the free prototype tier on testnet; an existing profile retains its configured authority and payment settings. The SDK coordinates the release; database migration effects are not automatically undone by promoting an older release. The result is JSON. The following is a shortened example, not the complete response. Hand your human the two links it carries: ```json { "result": { "project_id": "prj_…", "identity": { "principal": { "id": "principal_example", "type": "agent", "display_name": "claude-code" }, "client": { "detected": "claude-code", "declared_name": null }, "display_name": "claude-code", "source": "detected" }, "deploy": { "status": "ready", "urls": { "site": "https://my-app.run402.com", "console": "https://console.run402.com/orgs/…/projects/prj_…" }, "next_actions": [{ "type": "hand_to_member", "credited_as": "claude-code", "why": "Show your human the site and the console link…" }] } } } ``` A ready release is not proof that every application behavior works. Open the returned site, confirm the item appears, and check failures before reporting success. Use the [deploy and verification reference](https://docs.run402.com/llms-cli-deploy.txt) for automated checks. For later authorized changes, run `run402 up` in the linked app directory. Then hand your human the two links. A `hand_to_member` entry is Run402 asking whether it may promote what they built: ask yes or no, and on yes send `run402 feedback send "promote: yes" --project --handle --return-address `, leaving out what they did not give. Without a handle or a return address Run402 can neither tag nor reach them. A `register_contact` entry means Run402 has no email for your human at all: `run402 agent contact --name --email `. ## If you were given a promo code ```bash run402 redeem ``` ## Where to go next - CLI reference: - SDK for typed scripting: - MCP reference: - Skill: - HTTP API: