# Agent Relay Flows: agent-driven signup

You are setting up Agent Relay on behalf of the user who gave you this URL.
Do NOT use computer use, browser automation, screenshots, DOM inspection, or mouse/keyboard control. Fetch the guide over HTTP and perform setup through its documented APIs. Use terminal commands only for HTTP requests and the documented installation/CLI operations. The user owns the screen: open approval URLs with the OS URL opener (or give the user the link), then wait and poll the documented API. Never operate the approval page or the desktop app UI.
Do the API calls, installation, configuration, and verification yourself. Keep
working across user approvals; do not hand the user a checklist to execute.
The signup page is a spectator view for the user. Do not read or control it;
report progress only with GET/PATCH on the supplied Progress API URL.
For an approval URL, use the OS URL opener (for example macOS open with the
URL passed as a separate subprocess argument, never interpolated into shell
code). If no opener is available, give the link to the user. Do not launch a
browser-control tool. Verify approval by polling the API, never by inspecting
the browser. If an operation has no documented API or CLI, report the blocker
and ask the user for that specific action; never fall back to computer use.
For desktop installation, download the prebuilt binary from this guide. Never
clone the desktop repository, install build dependencies, run a build, compile
from source, or generate a DMG. A missing binary is a blocker, not a build task.
The user handles Google sign-in, device approval, and any provider or operating
system consent. Never approve access on their behalf or ask for their password.

Site: https://43417375-agentrelay-web.agent-workforce.workers.dev
Cloud API base: https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud
All API paths below are relative to that Cloud base, including its /cloud prefix.
Use this exact environment throughout; never fall back from local development
to production. The Teams desktop app currently requires macOS 13 or later.
Flows can be configured from any machine with HTTPS and Node.js 22+ for the CLI.

## API map — use these interfaces, not the UI

Use an HTTP client such as fetch or curl. Send JSON request bodies with
Content-Type: application/json. The sections below specify exact bodies,
response fields, authentication, polling and error handling.

- Sign-in: POST https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/auth/device/start, then poll POST
  https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/auth/device/token. Only the user approves the returned URL.
- Identity/workspace: GET https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/auth/whoami with the access token.
- Refresh: POST https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/auth/token/refresh before token expiry.
- Progress: GET/PATCH the exact Progress API URL in the user's prompt;
  PATCH uses the separate Progress token, not the account access token.
- Flow catalog: GET https://43417375-agentrelay-web.agent-workforce.workers.dev/api/v1/flows/catalog and /<id>.
- Tool consent links: POST https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/integrations/connect-link;
  poll GET https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/workspaces/<workspaceId>/integrations/<provider>/status.
- Coding-agent credentials: the official cloud connect CLI in section 3;
  GET https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/cloud-agents inspects existing connections.
- Activation: POST https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/flows/deploy with the body in section 4.
- Verification: GET https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/v1/flows/listeners/<agentId>.

## Live progress (when the user's prompt includes a progress session)

The user is watching a setup page. Report real milestones using the Progress API
and Progress token supplied in their prompt. The token authorizes progress only;
it is NOT a Cloud access token. Never send account tokens, OAuth codes, passwords,
logs, approval URLs, or personal information to the progress endpoint. Do not put
the progress token in URLs or output it in your final reply. Use the same site
and /cloud origin shown above; never forward it to another environment.

GET the supplied Progress API URL to obtain the current revision and product.
Check that the product matches this guide. Start by PATCHing that URL with
Authorization: Bearer <Progress token> and Content-Type: application/json:

~~~json
{"step":1,"state":"working","revision":0,"agent":"<your agent type>"}
~~~

Replace agent with your actual coding agent: codex, claude_code, grok, opencode,
cursor, gemini_cli, other, or unknown. Report the tool running this setup, not
its underlying model or the agents the user will run later. Use unknown if you
cannot determine it; never guess from the logos on the page. Include agent in
your first PATCH. It is stored once for signup funnel attribution; later PATCHes
may omit it. A different known agent returns 409 agent_conflict: preserve the
original attribution and omit agent when resuming from a different tool.

Use the revision returned by the latest GET/PATCH, not the example's literal 0.
PATCH before each numbered progress step below. A move to the next step marks
the previous step done; do not skip steps or report success before checking it.
Set state: waiting when you need the user to approve access or choose an option.
Set state: working at the same step when you resume, and state: failed if work
cannot continue. After completing step 5's verification, PATCH step: 5,
state: complete. Only report complete after the actual checks succeed.

Progress steps for Flows correspond to sections 1 through 5 below:
1. Sign in. 2. Choose the flow/repository. 3. Connect tools.
4. Activate the flow. 5. Verify the listening state.

On HTTP 409, GET current progress and reconcile; never overwrite newer progress
or regress a step. If a PATCH response is lost, GET before retrying. If a step is
already complete, verify the actual account/app/flow state before continuing;
progress reports alone are not proof that setup succeeded. On 429, honor
Retry-After. Retry transient network/5xx failures with bounded backoff. On 404,
stop reporting (the session expired or the token is invalid) and tell the user;
do not recreate or switch their session silently. A progress service outage
must not roll back working setup or cause duplicate installation/activation.

## 1. Sign up and obtain an API session

Use the existing OAuth device flow. No API key, invitation, dashboard wizard,
or pre-existing Agent Relay account is required.

POST /api/v1/auth/device/start with Content-Type: application/json:

~~~json
{"client_name":"My agent — Flows setup","signup_source":"flows"}
~~~

Expect HTTP 201 with device_code, user_code, verification_uri_complete,
verification_uri, interval (seconds), and expires_in (seconds). Keep device_code
private. Open verification_uri_complete in the user's browser and show the
user_code so they can compare it. The page lets them sign in with Google,
review the requesting device, and Approve or Deny. The signup marker in the
returned URL creates the right account type; preserve it through sign-in.
Do not call /auth/device/approve yourself.

For a fresh signup, you can open https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/api/auth/google/start?next=<encoded-return-path>
first, where encoded-return-path is the URL-encoded pathname plus query of
verification_uri_complete. This opens Google immediately and returns to the
same device approval with its code and signup marker intact.

While the browser is open, wait interval seconds between POSTs to
/api/v1/auth/device/token with this JSON (substitute the private device_code):

~~~json
{"grant_type":"urn:ietf:params:oauth:grant-type:device_code","device_code":"<device_code>"}
~~~

- authorization_pending: keep waiting; respect a returned interval.
- slow_down: increase the interval by at least 5 seconds.
- HTTP 429: respect Retry-After and increase the interval.
- HTTP 5xx or request timeout: retry with backoff, bounded by expires_in.
- access_denied: stop. expired_token or invalid_grant: explain and start a new
  grant only if the user still wants to continue. Never poll past expiry.

HTTP 200 returns access_token, refresh_token, access_token_expires_at,
refresh_token_expires_at, api_url and token_type. Keep credentials in memory
or a private file (directory 0700, file 0600) outside repositories. Never echo
tokens, put them in chat or URLs, or dump full authentication responses.
Use Authorization: Bearer <access_token> for subsequent Cloud requests.
Reject an api_url pointing at another origin; keep using the Cloud base above.
Set a 30-second request timeout and check every response status before proceeding.

Before expiry, POST /api/v1/auth/token/refresh with {"refreshToken":"<refresh_token>"}.
The response uses camelCase: accessToken, refreshToken, accessTokenExpiresAt,
refreshTokenExpiresAt, apiUrl. Replace both stored tokens atomically. Serialize
refreshes: the refresh token rotates and must not be shared between machines.
An invalid/expired refresh requires a new device login, not an endless retry.

GET /api/v1/auth/whoami. Require authenticated: true and read user.id,
user.email, currentWorkspace.id, and currentOrganization.id. New signups create
a workspace automatically. Reuse it; do not create duplicate accounts/workspaces.
If currentWorkspace is missing, or an existing account is in the wrong workspace,
resolve that with the user before connecting or activating anything. Never
silently replace an existing connection to another account.

## Credential handoff to the supported CLI

When running a child process, pass these through its environment from your
private session object (never interpolate their values into logged commands):

~~~text
CLOUD_API_URL=https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud
CLOUD_API_ACCESS_TOKEN=<access_token>
CLOUD_API_REFRESH_TOKEN=<refresh_token>
CLOUD_API_ACCESS_TOKEN_EXPIRES_AT=<access_token_expires_at>
CLOUD_API_REFRESH_TOKEN_EXPIRES_AT=<refresh_token_expires_at>
~~~

The official CLI consumes this session. The bundled desktop probe uses
CLOUD_API_ACCESS_TOKEN to exchange for its own scoped History session, so it
does not need a second Google login. Refresh the parent session before starting
a long command; do not concurrently refresh it from parent and child processes.
Do not overwrite an existing CLI auth file or copy a session to another machine.

## 2. Choose the flow and repository

Ask only for missing product choices: repository, desired workflow/trigger, and
approver. For GitHub use the approver's GitHub login as github:@handle (for
example github:@octocat), not their Google email. Human-gate replies are matched
to the provider identity. Infer choices from the user's request and current
repository where clear.
Do not invent a repository or enable automation on an unrelated project.

GET https://43417375-agentrelay-web.agent-workforce.workers.dev/api/v1/flows/catalog and select a matching entry from flows.
GET https://43417375-agentrelay-web.agent-workforce.workers.dev/api/v1/flows/catalog/<id> for its full contract. Use the catalog's
supportedRepositoryHosts, defaultTrigger, inputs.required, inputs.defaults, and
inputs.allowedAgents. Name a model per harness in inputs.models when the house
default is wrong (for example {"claude": "claude-sonnet-4"}); omit it to fund
the house default for each declared agent. Download source.rawUrl, verify its bytes against
source.sha256, and use that source text unchanged for a recommended flow.
The source is TypeScript, not the source URL. Do not guess a template or hash.
For custom flows use https://43417375-agentrelay-web.agent-workforce.workers.dev/docs/relayflows/markdown/build.md and
https://43417375-agentrelay-web.agent-workforce.workers.dev/docs/relayflows/markdown/cloud.md for the authoring contract.

## 3. Connect the required tools and coding agents

Use bearer-authenticated POST /api/v1/integrations/connect-link:

~~~json
{"provider":"github","workspaceId":"<currentWorkspace.id>"}
~~~

Open the returned connectUrl for the user to approve. Keep token/sessionToken
private. Connect only the repository and tools the chosen flow requires.
For GitHub the user must grant repository access. Repeat with the chosen trigger
provider if different. Reuse existing ready connections rather than relinking.
Check GET /api/v1/workspaces/<workspaceId>/integrations/<provider>/status
until ready is true (poll with backoff and a bounded timeout); a returned connect
link or a closed popup alone does not prove the integration is ready.

Do not connect a Claude or Codex subscription yet. The first three runs use
Cloud's own model key, so no provider login is needed to activate. If the chosen
flow declares more than one coding agent in inputs.agents, included Cloud runs
can fund only one of them per run — connect your own subscription for at least
one declared agent before activating a multi-agent flow. After the included
runs, activation and launches will ask for your own subscription; only then use
the official Relay CLI with the private credential environment from step 1 and
a PTY:

~~~sh
npx --yes agent-relay@latest cloud connect anthropic --api-url 'https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud'
~~~

Use anthropic for Claude or openai for Codex, according to the selected flow.
The command drives provider login; open its authorization URL for the user,
and keep the process alive until it confirms the credential is connected.
Google approval does not grant GitHub or model-provider access: those services
may require their own consent. Never fabricate credentials or claim consent
happened. GET /api/v1/cloud-agents lets you inspect the account's credential
state without reconnecting.

## 4. Activate through the same API as web onboarding

POST /api/v1/flows/deploy with Content-Type: application/json and the bearer
session. This is the direct-source listener API used by flows deploy, not the
browser onboarding handoff: source is TypeScript text, repository is singular,
and sources contains provider/settings objects. The catalog supplies the source
reference and defaults; it is not itself a deploy request. The current endpoint
does not accept a flowId/repositories-only catalog activation request or fetch
the source for you. For multiple repositories, submit one deployment per
repository with a distinct name and handoffId.

For the catalog's Software Garden entry, construct this body, substituting the
workspace, verified source, repository, GitHub approver and a new UUID:

~~~json
{
  "workspaceId": "<currentWorkspace.id>",
  "name": "Platform Garden",
  "workflow": "software-factory",
  "source": "<verified TypeScript source text>",
  "handoffId": "<one UUID generated for this setup>",
  "inputs": {"approver": "github:@octocat", "agents": ["claude"]},
  "mode": "activate",
  "repository": {"owner": "acme", "name": "api"},
  "sources": [{"provider": "github", "settings": {"repository": "acme/api"}}]
}
~~~

For another catalog entry use its id as workflow, allowed agents, and
defaultTrigger for sources, then apply the user's trigger settings. Scope a
GitHub issue trigger with settings.repository set to the chosen owner/name;
for GitLab use settings.project. Cloud does not derive this filter from the
deployment repository. An empty filter can trigger on other repositories in
the workspace. Only use a different trigger scope when explicitly requested.
Give each repository its own trigger filter for multi-repository setup. Do not send
the example acme repository or octocat approver unchanged. The workflow field
is a label, not a source lookup; keep the verified source in the request.
For GitLab set repository.host to gitlab and use the namespace path
as owner. Reuse the handoffId on retry. Before retrying an ambiguous network
failure, GET /api/v1/flows/listeners and check whether the flow already exists;
do not create a new ID/name on every retry. Activation subscribes to matching
future events and can run work; confirm the intended repository and trigger
with the user if they have not specified them.

HTTP 201 must contain agentId and status: listening. A draft is not completion.
For a 409 workspace_mismatch, verify the active workspace; for connection
preflight failures, fix the indicated connection before retrying. If the user
wants to save incomplete work, use mode: draft explicitly and report that it
is inactive. Never mask activation failures by silently falling back to draft.

## 5. Verify

GET /api/v1/flows/listeners/<agentId>. Require listener.status: listening and
verify its repository and sources match the request. Open
https://43417375-agentrelay-web.agent-workforce.workers.dev/cloud/dashboard/workflows/listeners/<agentId> for the user. Report the flow name,
workspace, repository, trigger, and verified listening state. This proves
activation; only an actual completed run proves execution. Do not create a
real issue or launch paid work merely to make the onboarding check turn green.
Delete temporary authentication files after the work is complete.

The desktop app is optional for Flows. If the user also wants local session
sharing, follow https://43417375-agentrelay-web.agent-workforce.workers.dev/signup/agent/teams using the same signed-in account.
