Ripple is a local project backlog and agent runner with a JSON API designed for coding agents and automation.
Start with:
GET /apiThe response links to this guide and the OpenAPI document:
GET /api/docs
GET /api/openapi.yaml- Every story belongs to a project.
- An epic is optional.
- Story descriptions are Markdown.
- Intended flow is
backlog -> queued -> in_progress -> in_review -> done(autonomous runs may skip visiblein_reviewand go straight todoneafter merge). donealways means the pull request was merged. Never mark done solely because a PR was opened.- Bots may only set story status to
backlog,in_progress, ordone. queuedandin_revieware human/orchestrator-only. Bots must not set them.- Bots must not close stories. Closing is a manual human review action in the UI.
- If a user says work is complete, move the story to
done, notclosed. - Closed stories are hidden from the default board and default story list.
| Status | Who sets it | Meaning |
|---|---|---|
backlog |
human or bot | Not queued |
queued |
human only | In the execution queue |
in_progress |
human, bot, or orchestrator | Active implementation or fix pass |
in_review |
orchestrator / human only | PR open; waiting on a human (supervised) |
done |
human, bot, or orchestrator | Merged |
closed |
human only | Archived after human review |
Stories use project-prefixed IDs such as ACM-001 or HBR-001.
Projects have a required prefix. When creating a project through a story request, provide projectPrefix if the user has a clear preference. If no prefix is known, choose a short uppercase prefix from the project name.
Projects may also have a workingDirectory. Use the Git repository root, or the folder where Codex should start work for that project. If a project already exists without a working directory, providing one in a later project or story request fills it in. Existing working directories are not overwritten silently.
Projects may set deliveryMode to agent (default) or backlog:
| Mode | Meaning |
|---|---|
agent |
One-repo agent delivery. Requires a working directory for runs. done means the PR was merged by the delivery loop. |
backlog |
Portfolio / planning backlog (e.g. AMPNET). Stories may span many repos via targetRepo. Agent queue runs are disabled. External tools pull and update stories through the API. In this mode done means the work item is resolved (not necessarily merged by Ripple). |
Projects may set autonomyMode to autonomous (default) or supervised (agent mode only). Autonomous runs implement, review, and merge without waiting. Supervised runs implement, open a PR, post an agent review, then stop with the story in in_review until a human acts: address review comments, merge the PR (with quality gate), or sync if the PR was already merged on GitHub. Invalid values are stored as autonomous. Agents cannot set status to in_review, queued, or closed.
Optional delivery fields for agent mode (all have safe defaults that preserve current behavior):
| Field | Default | Effect |
|---|---|---|
defaultBranchOverride |
empty (auto-detect) | Checkout branch before runs when auto-detect is wrong |
prBaseBranch |
empty (use default branch) | gh pr create --base |
qualityGateMode |
strict |
strict fails the run/merge on check errors; warn logs and continues |
deleteBranchOnMerge |
true |
Delete the feature branch on GitHub and locally after merge |
branchNameTemplate |
ripple/{id}-{slug} |
Feature branch name; placeholders {id}, {slug}, {prefix} (must include {id}) |
Implementer and Reviewer bindings live on the Settings page (app-wide, not per project). The Bot API does not configure agents. Defaults: Codex CLI implements; Grok CLI reviews. Either CLI may fill either role (including both). An OpenAI-compatible HTTP provider may be selected as Reviewer only.
Use this when you know the project before creating stories.
POST /api/projects
Content-Type: application/json
{
"id": "acme",
"name": "Acme",
"prefix": "ACM",
"workingDirectory": "/path/to/acme",
"deliveryMode": "agent",
"autonomyMode": "autonomous",
"defaultBranchOverride": "",
"prBaseBranch": "",
"qualityGateMode": "strict",
"deleteBranchOnMerge": true,
"branchNameTemplate": "ripple/{id}-{slug}"
}deliveryMode is optional and defaults to agent. autonomyMode is optional and defaults to autonomous. Delivery fields above are optional on create.
For multi-repo planning (no agent runs on this project):
POST /api/projects
Content-Type: application/json
{
"id": "ampnet",
"name": "AMPNET",
"prefix": "AMP",
"deliveryMode": "backlog"
}Use this when grouping related stories.
POST /api/epics
Content-Type: application/json
{
"projectId": "acme",
"name": "Onboarding polish",
"description": "Cleanup work for the first-run experience."
}Use this when the user asks to add, create, track, remember, or file a task, bug, feature, or work item.
You can reference an existing project:
POST /api/stories
Content-Type: application/json
{
"projectId": "acme",
"title": "Add dark mode toggle",
"description": "Add a setting so users can switch between light and dark themes.",
"status": "backlog"
}For portfolio projects, set targetRepo so consumers can filter by codebase:
POST /api/stories
Content-Type: application/json
{
"projectId": "ampnet",
"title": "Wire auth middleware",
"description": "Shared JWT validation for AMPNET services.",
"targetRepo": "ampnet-core",
"status": "backlog"
}Or create/find a project and epic while creating the story:
POST /api/stories
Content-Type: application/json
{
"projectName": "Harbor",
"projectPrefix": "HBR",
"workingDirectory": "/path/to/harbor",
"epicName": "Notifications",
"title": "Send weekly email digests",
"description": "Batch unread activity into a weekly email for subscribed users."
}If status is omitted, the server uses backlog.
Default listing excludes closed stories:
GET /api/storiesFilter by project, epic, status, target repo, or update time:
GET /api/stories?projectId=acme
GET /api/stories?epicId=acme-onboarding-polish
GET /api/stories?status=in_progress
GET /api/stories?projectId=acme&status=backlog
GET /api/stories?projectId=ampnet&targetRepo=ampnet-web
GET /api/stories?projectId=ampnet&updatedSince=2026-01-01
GET /api/stories?projectId=ampnet&updatedSince=2026-01-01T00:00:00ZupdatedSince accepts YYYY-MM-DD or RFC3339. Useful for external tools polling for changes.
Include closed stories only when the user specifically asks for archived or closed work:
GET /api/stories?showClosed=1External tools treat Ripple as the backlog source of truth:
- List open work:
GET /api/stories?projectId=ampnet&status=backlog&targetRepo=ampnet-core - Claim:
PATCH /api/stories/AMP-001/statuswith{"status":"in_progress"} - Finish:
PATCH /api/stories/AMP-001/statuswith{"status":"done"}
Use this to change title, description, epic, or target repo.
PATCH /api/stories/ACM-001
Content-Type: application/json
{
"description": "Updated Markdown description.",
"targetRepo": "ampnet-web"
}targetRepo may be an empty string to clear it.
Use this to move work through the bot-writable workflow.
PATCH /api/stories/ACM-001/status
Content-Type: application/json
{
"status": "in_progress"
}Allowed bot statuses:
backlogin_progressdone
Do not attempt to set queued, in_review, or closed; the API rejects them.
Use this when you need to understand what happened to a story.
GET /api/stories/ACM-001/events