Skip to main content
Complete the authentication setup. You need a user key that can build apps in your organization; a scoped key needs a grant to build all apps. You also need git, Node 20 or later, and pnpm. An app is a Git repository and the deployment Effective runs from it. You’ll create an app, change what its page shows, and deploy the change. The examples use an app called app-claims-notes in the acme workspace. IDs, commits, hashes, and URLs in them are illustrative; use the values your own requests return.

Create the app

Choose an ID: app- followed by lowercase letters, digits, and hyphens. It becomes part of the app’s hostname and can’t be changed.
Abbreviated 201 response:
You’ll clone source.gitUrl next. url stays null until the first deployment. 409 with app_exists means the ID is taken, possibly by an app you can’t see; choose another. See Create an app for the description, icon, and visibility.

Change the interface

Git uses your API key as the password; any username works. Set the header once, then clone source.gitUrl and start a branch:
The starter is in apps/app-claims-notes/. Its backend, worker/app_backend.py, answers GET /api/health with the signed-in user’s ID. Its page, ui/src/App.tsx, calls that route and shows “API Connected”. Make the page show who is signed in. In ui/src/App.tsx, replace the {data && (...)} block with:
data is the JSON that apiFetch('health') returned. Use apiFetch for any route you add to worker/app_backend.py; it adds /api/ and the user’s credentials. Install the interface’s dependencies, then run its tests and type-check it:
The build runs the same checks and stops if either fails. The backend runs only in the deployed app, so you’ll see the page working after you deploy. pnpm install created ui/pnpm-lock.yaml, which the build needs. Commit it with your change and push the branch:
You can’t push to main; deploying merges your branch into it.

Build the release bundle

From the repository root, run the builder that comes with the starter:
It builds the last commit and stops if the clone has uncommitted or untracked files, so write the bundle outside the clone. It installs the locked dependencies, runs the tests, type-checks, and builds the interface. The first run can take a few minutes. It prints:
sourceSha is the head of show-user. You’ll send it, bundleSha256, and bundleSizeBytes in the next two requests.

Upload the bundle

Request an upload URL:
Set UPLOAD_URL to upload.url and PUT the bundle to it within 15 minutes. Send the header the response names, and don’t send your API key:
The upload request is safe to repeat. Once the bundle is stored, it returns "uploaded": true; if the URL expired, it returns a new one.

Deploy

Deploy the bundle from the branch you pushed:
Effective checks the bundle against the files at sourceSha, squash-merges show-user into main, and deploys. This can take a minute. Abbreviated 201 response:
current: true means the app now serves this deployment. sha is the merge commit on main. If main changed after you branched, the deploy returns 409 with source_main_changed or source_merge_conflict. Rebase your branch onto main, force-push it, then build, upload, and deploy again. Do the same after 502 with deployment_failed: main already holds your change, but the previous deployment is still current. Deploy an app lists the other errors. Start your next change from the updated main:

Open the deployed app

Get the app’s url:
Abbreviated response:
Open url in a browser and sign it in. The page shows “Signed in as user” and your user ID. Next, test the app and set its secrets.