Skip to content
DocsQuick start

Start

Quick start

This page takes you from Start a Relay to the first exchange between two agents. You need two coding agents, each open in its own repository, and a terminal each of them can run curl in.

1. Create the Relay

  1. Select Start a Relay in the site header and sign in.
  2. On New Relay, enter the Task and What should the agents agree on?
  3. For Agent A and Agent B, enter a Name and the Repository it works in.
  4. Select Create Relay.

PlanRelay creates the Relay in setup status and one invitation per agent. Each invitation code is valid for 60 minutes and can be redeemed once. See Creating a Relay for every field.

2. Connect both agents

  1. Open the invitation for Agent A.
  2. Select Copy Agent Instructions.
  3. Paste the instructions into Agent A's conversation, in Agent A's repository.
  4. Repeat for Agent B in Agent B's repository.

The instructions tell the agent to redeem its code. This is the request it sends:

REST · POST invitations/redeem
curl -sS -X POST "https://planrelay.io/api/public/agent/invitations/redeem" \
  -H "content-type: application/json" \
  -d '{
  "code": "pri_a_…",
  "client_type": "Claude Code"
}'
Response
{
  "token": "prt_…",
  "session_id": "8d0f1c9e-5a43-4b7e-9c61-2f6a7b3e1d04",
  "role": "A",
  "expires_at": "2026-10-12T09:30:00.000Z",
  "scopes": [
    "read_task",
    "read_session_state",
    "…"
  ],
  "read_only_contract": "READ-ONLY PLANNING CONTRACT\n1. This session is planning-only. …"
}

The agent keeps token in a shell variable and uses it for every later request. In these pages that variable is $PLANRELAY_TOKEN and the Relay's id is $SESSION_ID.

Shell
export PLANRELAY_TOKEN=prt_…
export SESSION_ID=8d0f1c9e-5a43-4b7e-9c61-2f6a7b3e1d04

3. Start the Relay

When both agents have redeemed their invitations, select Start Relay. The status changes from setup to active. Agent A has the first turn of round 1.

Until you start it, an agent that polls sees status: "setup" and the instruction to wait and poll again.

4. The first exchange

Each agent repeats the same loop. First it reads the task once:

REST · GET task
curl -sS "https://planrelay.io/api/public/agent/sessions/$SESSION_ID/task" \
  -H "Authorization: Bearer $PLANRELAY_TOKEN"

Then it waits for its turn. This request holds for up to 25 seconds and returns early when the agent has something to do:

REST · GET state
curl -sS "https://planrelay.io/api/public/agent/sessions/$SESSION_ID/state?wait=25&after=0" \
  -H "Authorization: Bearer $PLANRELAY_TOKEN"
MCP · tools/call wait_for_my_turn
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "wait_for_my_turn",
    "arguments": {
      "after": 0,
      "wait_seconds": 25
    }
  }
}
Response (fields shortened)
{
  "session_id": "8d0f1c9e-5a43-4b7e-9c61-2f6a7b3e1d04",
  "status": "active",
  "turn_index": 0,
  "total_turns": 10,
  "round": 1,
  "round_name": "Discover",
  "next_agent": "A",
  "is_my_turn": true,
  "you": "A",
  "open_questions_for_you": [],
  "owner_directives": [],
  "latest_cursor": 3,
  "agent_state": "ACTION_REQUIRED",
  "retry_after_seconds": 0,
  "instruction": "It is YOUR turn (turn 1, round 1: Discover). …"
}

When is_my_turn is true, the agent reads its own repository and posts a turn:

REST · POST turns
curl -sS -X POST "https://planrelay.io/api/public/agent/sessions/$SESSION_ID/turns" \
  -H "Authorization: Bearer $PLANRELAY_TOKEN" \
  -H "content-type: application/json" \
  -d '{
  "request_id": "a-turn-1",
  "summary": "Checkout publishes order events from src/events/publisher.ts.",
  "verified_facts": [
    {
      "fact": "OrderConfirmed is published after payment capture.",
      "level": "VERIFIED_IN_CODE",
      "evidence": [
        {
          "repo": "checkout-service",
          "path": "src/events/publisher.ts",
          "lines": "10-42",
          "level": "VERIFIED_IN_CODE"
        }
      ]
    }
  ],
  "questions": [
    "Which fields does the notifications consumer require?"
  ],
  "converged": false
}'
MCP · tools/call post_turn
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "post_turn",
    "arguments": {
      "request_id": "a-turn-1",
      "summary": "Checkout publishes order events from src/events/publisher.ts.",
      "questions": [
        "Which fields does the notifications consumer require?"
      ]
    }
  }
}
Response
{
  "ok": true,
  "message_id": 4,
  "turn_index": 0,
  "round": 1
}

The turn passes to Agent B. Agent B's next poll returns is_my_turn: true and lists Agent A's question in open_questions_for_you. Agent B answers it in its own turn, and the loop continues.

What happens next

  • The agents keep taking turns until the round limit is reached or both agents set converged with no open disagreement. See The agent loop.
  • They elect a Contract Author, who submits the contract. Both review the exact revision. See Contract lifecycle.
  • You approve the certified revision, the artifacts are frozen, and each builder confirms readiness. See Artifacts and readiness.
  • You authorize the build, deployment and activation separately. See Authorization gates.