Relay Relay / Docs Open the board
Menu

GET STARTED

Getting started

From nothing to a card being worked by agents. Follow the steps in order — each one is a board URL, a click in the UI, or a command you already have. Nothing here needs access to Relay's own source repository.

This page is written so an agent can follow it. Where you need a human to decide something, it is called out as a question.

1. Create a board

Sign in at your board host and create a board. That is the whole of setup. Creating a board seeds:

  • its stages (columns) and their human/AI ownership;
  • the Spec:Review, Spec:Done and Plan:Done lanes;
  • the default flows — Spec, Plan and Code.

A board created from a template also opens a setup wizard beside it, which walks you through the steps below and ticks each one as the board sees it happen. Nothing needs importing. The seeded flows arrive disabled; step 5 is where you turn one on.

Note your board's URL — it looks like https://<board-host>/board/<slug>. The <slug> appears in every board URL below.

2. Get a board API key

Open Settings → API keys on your board (/board/<slug>/settings) and click + Create new key. It is shown once — copy it now. If a key already exists, Regenerate replaces it.

Point your shell at the board with two environment variables:

export RELAY_URL="https://<board-host>"
export RELAY_API_KEY="relay_xxxxxxxxxxxx_…"

Put them somewhere your agent's shell will load them — a gitignored .envrc.local, your shell profile, or your process manager's environment. Every command below reads them.

See Authentication & API access for what the key authorises and the error you get without it.

3. Get the CLI and scaffold your project

Everything the CLI needs is served by your board — no access to the Relay repository is needed, there is no repository to clone, and nothing comes from a third party.

Create the board from a template and follow its setup wizard, docked beside the board. Step 4 of the wizard gives you the install command for your board — run it once, from the root of your project's git checkout:

curl -fsSL "https://<board-host>/b/<slug>/install" | sh

The script checks your project first and writes nothing until those checks pass. Then it fetches ./relay from $RELAY_URL/api/scaffold/relay with your board's URL already baked in, so the CLI finds its board without RELAY_URL (an exported RELAY_URL still overrides it, and ./relay update keeps it). It also installs the Relay-owned skills and relay.md, and lays down a starter .relay/runner.json and .relay/prepare-worktree.sh with ./relay update --starter-only — that is where step 4's capacity configuration comes from. Your board API key is never written to disk.

Then start Claude Code in the project and run /relay-onboard, which wires this repo to your board's flows and reviews the starter .relay/runner.json with you. It works sub-steps 5.1–5.8 of the board's setup checklist, one at a time, reporting each one to the board's setup wizard as it goes: pull the flows, confirm what it found in the repo, ask the questions the repo can't answer (saved to a committed .relay/project.md), agree each proposed change with you before writing anything, push the flows back enabled, get Relay's files onto your base branch, file any follow-ups as #setup cards, and create your first card. Interrupt it any time; running it again picks up where it stopped. On a board created before guided setup it says so and points you at /relay-doctor.

Relay owns exactly five files in your project and updates them as a set:

Item Path
the runner ./relay
the agent guide relay.md
updater skill .claude/skills/relay-update/SKILL.md
doctor skill .claude/skills/relay-doctor/SKILL.md
onboarding skill .claude/skills/relay-onboard/SKILL.md

Everything else in .claude/ is yours; Relay never writes it.

Already have ./relay? Run /relay-update (or ./relay update --check to see what would change first). It compares the board's scaffold manifest against what is on disk, refetches only what actually differs, and restores anything that has been deleted or edited.

Question for a human: which project directory should agents work in? It must be a git repository, and it should be one you are willing to let agents create branches in.

4. Start the runner

From that project directory:

relay start

The runner claims work from your board and runs it. It knows nothing about your board's particular columns or agents — the server tells it what to do, so it stays generic. It long-polls when idle, so leaving it running is cheap.

Confirm it is advertising capacity before moving on. Open the Runners view at /board/<slug>/runners. Your machine should appear with a FRESH pill and capacity chips showing its configured totals. If it does not appear at all, relay start is not reaching the board — re-check RELAY_URL and RELAY_API_KEY from step 2.

Capacity comes from .relay/runner.json's capacity and is advertised on a heartbeat every few seconds. Two classes matter:

  • shared_clean — jobs that can share one clean worktree;
  • exclusive — jobs that need a worktree to themselves. The Code flow needs this one.

If your trunk is not main, set base in the same file — it is the ref every worktree is created at and reset to, and it defaults to origin/main:

{ "capacity": { "shared_clean": 1, "exclusive": 1 }, "base": "origin/master" }

Note that base governs worktrees, not branches: where a card's branch starts is written into the flow's branch node, and changing it is a flow edit.

Usage limits. Add "limits": {"max_five_hour": 0.9, "max_seven_day": 0.9} to the same file to stop the runner claiming new work once Claude usage passes 90% of the five-hour or seven-day window. Jobs already running finish, the Runners view marks the machine RATE LIMITED, and it resumes on its own when the window resets. Leave a key out for no limit on that window.

5. Enable a flow

Flows are seeded disabled, so nothing dispatches until you turn one on. Open Settings › Stages on your board and turn on the Spec flow in the Spec stage's FLOW band — it is the cheapest one to start with, and it is the first stage a new card meets.

The confirm dialog reminds you that a runner must be connected and advertising capacity before cards will move — it does not check for you, so confirm that yourself on the Runners view (step 4).

Read Enabling a flow safely before you enable a flow on a board that already has cards moving through it — the ordering there is what keeps two dispatchers off the same cards.

Question for a human: which stages do you want agents to own? Enabling a flow hands that stage's cards to agents. Start with one.

6. Move a card into Next up and watch it work

Create a card on the board and drag it into the Spec stage's Next up lane. Within a few seconds the card should pick up a Run: open the card's drawer and select the Run tab to watch the agent work, live.

When the flow finishes, the card moves itself to the next stage. If the agent hits a decision it cannot make, it sets the card to needs input and asks you a question in the drawer — answer it there and the run resumes.

See Statuses & outcomes for what each state means.

7. When a card does not move

A card that just sits in Next up is almost always one of four things. Check them in this order:

  1. No flow is enabled for that stage. Open Settings › Stages and confirm the FLOW band on that card's stage is on. This is the most common cause on a new board.
  2. No runner is advertising capacity. Open /board/<slug>/runners. If the roster is empty, or your machine shows STALE or GONE rather than FRESH, relay start has stopped or lost the board — restart it and re-check.
  3. The runner has capacity, but not the right class. A Code-flow card needs exclusive capacity. Check the capacity chips on the Runners view against what the flow needs.
  4. The card is blocked on you. A card in needs input is waiting for a human answer, not for an agent. Open its drawer and answer the question.

If none of those explain it, open the card's drawer Run tab: a run that started and failed shows the node that failed and its outcome there.

Tip

There is a dedicated diagnosis surface for exactly this question: run ./relay why <ref>, or read GET /api/cards/:ref/diagnosis. It answers "why isn't this card moving?" in one call instead of four checks by hand.

Where to go next