Skip to main content
This guide walks the whole loop once: install the CLI, create an agent, let a coding agent author it, prove it with runs, read a trace, and publish a version the API and SDK will serve. You work in two places, and they are the same agent. The CLI is where the program is authored and proven. The Playground is where you watch it talk, read any turn in a UI, change it from what you see, and hand it to people who don’t live in a terminal. They edit one bundle and run one engine — see The Playground for using them together.
1

Install the CLI

Then sign in — the browser opens and returns you to the terminal:
Node.js 20 or later is required. Bun is optional, and only for the interactive TUI. See Installation for the other sign-in modes and for shell integration.
2

Start every session with an upgrade

The CLI ships frequently, so make this the first thing you run each day. Commands and flags do change between builds, and a stale CLI is the most common source of confusing errors. apollo upgrade --check reports the available version without installing it.
apollo doctor diagnoses the whole setup — runtimes, install origin, credentials, the current checkout, service reachability — with the fix attached to every finding.
3

Create the agent

You can run apollo agent create "My agent" yourself, but the CLI is built to be driven by a coding agent — Claude Code, Cursor, or the Playground’s own Builder. Hand your coding agent a prompt like this one:
Prompt for your coding agent
Creating the agent also creates a local checkout — a directory holding that one agent — and installs the authoring skill packs and AGENTS.md that teach a coding agent how Apollo programs are written. That is why the prompt says to read them first: the guides are versioned with the engine, so they describe the language your agent will actually be validated against.The last sentence matters as much as the first. The gaps worth catching are the ones in your own description of the job, and they surface as questions before any of it is written down.
4

Let it author

From here your coding agent edits the program under bundle/src/ and checks its work as it goes — apollo validate for the structural verdict, apollo chat "…" --local . to talk to the working tree before anything is pushed.What it is building is a typed YAML program: the nouns the agent can know, the jobs it can do, the rules that gate them, and where its facts come from. You do not need to know that language to get through this guide — see The agent program when you want to read what was written. Your job at this stage is to answer its questions and say whether the behavior it describes is the behavior you meant.
5

Prove it with runs

Structure passing is not behavior working. Replay the scripted suite through the simulator — this needs no push, so it runs against the tree you have:
The exploratory lane comes after the next step, because it binds to a pushed version. Both are described in Evaluations.
6

Push, then probe

A push mints the next revision on the draft you are bound to. Pushing is not publishing — nothing reaches callers yet.
7

Publish it

Publishing freezes the version and makes it live for callers — see Versions.

The two folders

A checkout has two lanes, and the split explains everything that follows: bundle/build/ is where evaluation lives. It travels with the agent as a build bundle so anyone picking up the checkout inherits the evidence, but it is never served to a caller. As the agent is built or changed, these update together, so the coverage map — which needs are served, which cases are covered, which are not yet — stays honest rather than becoming a wish list.
The two lanes are siblings, never nested: proof material written into bundle/src/ is a build error, and nothing under build/ may be referenced from the program.
The case bank is never edited to make a run pass. A red run means the agent is wrong, or the case was wrong in a way you can argue for out loud — not something to quietly relax.

Evaluations

Two lanes run the agent for real. Both ship your checkout to a detached server-side run against a snapshot frozen at start — so you can keep editing while it runs — and both remember the run, so a later --status or --pull finds it. One live run per lane at a time.

The built-in suite: regression

apollo regress drives the scripted suite in bundle/build/scenarios.yaml through the simulator: every turn said exactly as written, one real conversation per scenario, nobody improvising. This is the “does what worked still work” lane, and it needs no push — it runs on the tree in front of you.
With the judge off, a scenario passes when its script ran clean end to end. --judge also grades each conversation against the cases it covers in bundle/build/cases.yaml. --follow waits and exits 2 on red, which is what you want in CI. It reports; it gates nothing.

Your own evaluations: exploration

apollo evaluate goes looking for what no script covers. You say what to probe in plain words, and the planner turns that — together with the bundle’s own records in cases.yaml, needs.yaml and world.yaml — into improvising simulated callers. A judge grades each conversation, and the run ends on a macro verdict: a summary, the findings, per-case coverage, and candidate regression scenarios worth adopting into the scripted suite. Push first. The run binds to a real version, so apollo push before you evaluate.
Aim the guidelines at what your change affects. Running the whole case bank is a decision for whoever owns the agent, not a default. Either lane can be read later rather than watched. --status reads a settled run’s report; --pull fetches the evidence into tmp/regressions/<id>/ or tmp/evaluations/<id>/ — a scoreboard, and per trial a transcript, a trace and a verdict. Read those files rather than the terminal output when you are diagnosing a failure. --annotate "…" --verdict mixed appends your reading to a settled run for the next person; the machine’s verdict underneath never moves.

Who the callers are

Simulated callers are drawn from bundle/build/world.yaml — identities (a specific person, with a record behind them) and personas (how they behave: cooperative, eager, entitled, unsure). Give it your own sample users by writing them there, or let the mock database stand in for the system of record they’d come from.

The mock database

Most agents need a backend before there is one to point at. apollo mockdb gives each agent a private database it can read and write during development: collections you define, rows you seed, and named endpoints the program’s sources call through connections.yaml.
Date fields can be written as relative tokens such as now-30d, so seeded data stays fresh instead of ageing into nonsense.

Copy-on-write, so tests stay repeatable

Writes are copy-on-write, keyed by session. The base rows you seeded never change; each conversation gets its own overlay on top of them. A test that cancels an order, files a claim, or updates a record sees its write land, and the next run starts from pristine base data again. Exercising writes never corrupts the fixture, so a suite can be run as many times as you like and mean the same thing each time. You get this for free during testing: the session key is the conversation’s own thread id, so every conversation — every trial in a run included — is isolated from every other without you arranging anything.
Reads may skip --session to peek at the pristine base; writes require one.
apollo mockdb describe reads the base only. An empty result after a conversation wrote rows is correct, not lost data — the write is in that conversation’s overlay. Look for it with apollo mockdb session get --key <thread-id>.

Personas for the Playground

apollo mockdb identities holds the sample users the Playground’s simulator offers in its picker, so anyone opening the agent in the browser can pick “Jane Doe (verified)” and talk to it as her:
Every persona value must already exist in the mock database — the persona names a row, it does not create one. set replaces the whole payload, and an empty personas array turns the picker off.

Traces

Every interaction produces a full structured trace: what the message was taken to mean, which facts were already held and which were fetched, which rules were evaluated and what they did, what was computed, what ran, and what the reply rested on. This is the instrument you diagnose with. A failing case tells you that the agent was wrong; the trace tells you which element — a missing fact, a gate that fired on the wrong condition, a source that returned nothing — so you know what to change.
Runs carry their traces too — apollo regress --pull and apollo evaluate --pull fetch the conversations and traces of a settled run into tmp/ so you can read the failures offline. In the Playground, the same trace is rendered beside the conversation, turn by turn. To pull traces from your own application rather than the terminal, see Traces for the API and the SDK.

The Playground

The Playground is the same agent with a UI around it. Think of the two surfaces as backend and frontend views of one thing: the CLI holds the files, the runs and the versions; the Playground holds the conversations, the traces and a builder anyone on the team can drive. Most work happens with both open.

Every thread lands here

Conversations you start with apollo chat show up as threads, and so does every trial a regress or evaluate run creates. A run is not a black box that returns a score — each simulated conversation is a real thread you can open and read turn by turn, with the trace beside each reply. When a run comes back red, this is where you go to see what the agent actually said and why. You can also just talk to the agent here. The persona picker offers the sample users you authored with apollo mockdb identities, so you can hold a conversation as a specific seeded user and watch the same trace a run would produce.

The Builder, on the left

The left pane is the program — readable as a structured view or as the raw files, and editable in plain language by the Builder, a coding agent working in the browser. It writes the same YAML the CLI edits and validates it the same way, so a change made here is a change made to the same bundle. Two things it is especially good at, and both start from a thread you have just read:
  • Change this. Point at the behavior you saw — “on turn three it offered a refund before checking eligibility” — and have the Builder make the change.
  • Explain this. Ask why the agent did what it did in that thread. The answer is grounded in the program and the turn’s trace, not guessed.
That loop — watch a conversation, fix or interrogate it on the spot — is what the Playground is for, and it is open to people who will never run a terminal command: an operations lead, a compliance reviewer, a product owner.
Pull after the Playground pushes. Changes made in the browser mint new revisions remotely, and your checkout has no idea. Before you edit files again:
That is usually all it takes — a stale pin resolves forward to the tip of the line you are bound to, so v1.4 finds v1.6. If the Playground locked the version, though, work continued on a fresh draft on a new line that your checkout does not point at, so bind it first:
apollo pull refuses to overwrite local changes — push what you have, or set it aside, before pulling (--force discards them). A successful pull makes bundle/src and bundle/build match the remote snapshot exactly, including deleting files that are no longer there. Skip this and your next push builds on a version that has already moved.

Versions

A version tag looks like v1.2 — a version line and a revision within it. Each apollo push commits a new revision onto the draft you are bound to, so the tag moves v1.1 → v1.2 → v1.3 as you work.
A version has one of three states: draft (open, still taking revisions), published (frozen, and exactly one published version is live), or archived (retired, kept in history). Publishing freezes the version. Publishing a draft freezes it and then makes it live, and a frozen version stops taking revisions — push onto it and you get a fresh draft forked from it, leaving the published one exactly as it shipped. That is how a version you rely on is protected from further commits.
Freezing without shipping. The Playground can also lock a version: it freezes exactly as it is and a fresh draft opens beside it, while the live pointer stays where it was. Use it to protect a version that is finished but not yet the one callers should get. The CLI has no lock verb — from the terminal, apollo version publish freezes and goes live together.
To start a fresh line rather than continue the current one — a variant for another market, a rewrite you don’t want landing on the version in flight — create one and bind it:
apollo version use sets the base your pushes land on. It does not change what callers get — that is the published version, and only publish moves it.

Deploy

There is no deploy step beyond publishing. The API and the SDK serve the agent’s published version automatically, so publishing is what reaches callers, and re-publishing an older version is the rollback. Your integration doesn’t change when you ship: the same key keeps pointing at whatever is live. Callers always get the live version — a normal send carries no version pin. To exercise a version that isn’t live yet, bind it in your checkout and talk to it from the CLI (apollo version use v2.1, then apollo chat), or replay an existing turn against it with version_tag on rerun.

Connect from your app

Send a message and read the reply over REST, or stream it over server-sent events.

Use the SDK

ApolloMessagingClient for end-user messaging, ApolloManagementClient for operating agents and versions.

Authentication

Publishable keys for the browser, organization API keys for your backend.

Trigger from your systems

POST an event from a ticketing platform, CRM, or internal tool to start a conversation.

Where to go next

Command reference

Every command, flag, and exit code.

Workflows

The day-to-day loops once the first version is out.

The agent program

What is actually in bundle/src/, and how the pieces meet at runtime.

Configuration

Checkout layout, config files, and environment variables.