Skip to main content
Fixes pair a candidate change with a replay-gate verdict on held-out production evidence. These endpoints mirror the Fixes dashboard and are what the moda fix CLI family calls.

Base URL and authentication

Unlike the rest of the Data API, the fix routes are tenant-scoped and live under the control-plane base:
They accept the same x-api-key header as the Data API (a dashboard session also works). Reads require workspace membership; every mutation (POST) requires the admin role. Responses use camelCase field names — except the fix packet, which is snake_case by design (it is an agent-facing document).

Endpoints

The Fix object

Every fix endpoint (except the packet) returns or embeds this shape:

Statuses

DRAFT, SCOPING, NO_EVIDENCE, BLOCKED_COVERAGE, UNROUTED, PROPOSING, NO_HEADROOM, PROPOSED, GATING, GATE_FAILED, GATE_INCONCLUSIVE, VERIFIED, PR_OPEN, APPLIED_LOCALLY, HANDED_OFF, SHIPPED, CONFIRMING, HELD, REGRESSED, REJECTED, SUPERSEDED, ABANDONED. The dashboard lifecycle table explains each stage.

Gate result

gateResult is set once a gate finishes:
The verdict reads holdout cases only. pass requires wins − losses ≥ max(2, noiseFloor + 1), losses ≤ noiseFloor, and abstained ≤ 30% of the holdout; more than 30% abstained is inconclusive (never a pass); anything else is fail.

POST /tenants/:tenantId/problems/:problemId/fixes

Drafts a fix. Creation is idempotent while a fix is active: drafting again for the same problem returns the existing active fix instead of forking the pipeline. The new fix rests at DRAFT — drive it with advance.
string
default:"auto"
auto routes from evidence; prompt considers only the prompt route.
A malformed (non-UUID) problem ID returns 400; an unknown problem returns 404. A merged-away problem ID is folded to its survivor, like the problem endpoints.

GET /tenants/:tenantId/fixes

The ranked queue: fixes ordered by their problem’s rank (descending), then recency. Also available per problem at GET /tenants/:tenantId/problems/:problemId/fixes (returns { "fixes": [...] } without pagination).
string
Filter to one status. An unknown status returns 400.
integer
default:"25"
1–100.
string
Opaque cursor from a previous page’s pagination.next_cursor.
Reading a fix reconciles its confirmation state lazily: SHIPPED/CONFIRMING fixes are checked against the problem’s lifecycle on every read, so a reopen or 14 clean monitoring days surface as REGRESSED/HELD without a background job.

GET /tenants/:tenantId/fixes/:fixId/packet

The compact agent packet — moda.fix_packet.v1. Every fix has one, including diagnosis-only fixes without a candidate. Quoted evidence in the packet is neutralized as untrusted data before it reaches an agent.
target keys, candidate, and evidence entries are omitted when unknown (for example an UNROUTED fix has only fix_type in target and no candidate).

POST /tenants/:tenantId/fixes/:fixId/advance

Performs exactly one idempotent pipeline step and returns the updated fix. The backend runs no background jobs — clients drive the pipeline by calling advance in a loop (this is what moda fix … --wait and the dashboard polling loop do). Steps are claimed optimistically, so concurrent advances never double-run a stage; the loser returns the current row untouched.

POST /tenants/:tenantId/fixes/:fixId/verify

Re-gates the fix: enqueues fresh gate and control runs and returns the pinned gate run ID. With candidateContent this gates uploaded local content instead of the stored candidate — the fail-to-pass loop behind moda fix verify --prompt-file. Then drive advance until the fix leaves GATING.
string
Optional candidate content, 40–200,000 characters. Omitted = re-gate the stored candidate version. Uploaded content is recorded by hash (candidateRef.contentSha256), not registered as a prompt version.
Allowed from PROPOSED, VERIFIED, GATE_FAILED, and GATE_INCONCLUSIVE. A fix already GATING returns 409 (“advance to poll it”), as does any other status.

POST /tenants/:tenantId/fixes/:fixId/submit

Delivers a VERIFIED fix (any other status returns 409).
string
required
pr — Moda’s GitHub App opens a draft PR on branch moda/fix/<shortref> with the composed body and magic word. local_ref — records that you applied the change yourself on a branch (status → APPLIED_LOCALLY).
string
The branch name. Required when channel is local_ref.
Submit enforces the throttles: at most 3 open Moda fix PRs per workspace (409), one open fix PR per problem and per target file (409 names the sibling), and older drafts for the same problem or file are superseded. The pr channel requires a routed target file and a registered candidate version (400 otherwise — content verified via upload must be handed back as a PR by the agent itself); an unconfigured GitHub integration returns 503.

POST /tenants/:tenantId/fixes/:fixId/dismiss

Rejects the fix (status → REJECTED) and records the reason as problem feedback. Already-terminal fixes (REJECTED, SUPERSEDED, ABANDONED, HELD) return 409.
string
required
1–2,000 characters. Feeds the problem discovery loop.

Fix provenance on problem feedback (fix_ref)

When a PR whose body or head branch carries MODA-FIX-<SHORTREF> is merged, Moda’s GitHub App notifies the backend, which flips the fix to SHIPPED and posts a mark_fixed problem feedback with actor: "moda-github-app" and a structured fix_ref:
POST /problems/:id/feedback accepts the same optional fix_ref object on any mark_fixed you submit yourself. Notes:
  • fix_ref is stored on the feedback row and threaded into the problem’s lifecycle change reason for provenance; it is not part of the deterministic feedback_id, so re-asserting the same action with an amended ref converges on one row instead of minting duplicates.
  • If a problem that was marked fixed with a fix_ref later reopens automatically, the associated SHIPPED/CONFIRMING fixes flip to REGRESSED.
  • The merge notification is idempotent — redelivered webhook events converge on the same SHIPPED fix and the same pending feedback row.

Errors

Next steps

  • Dashboard: Fixes — the same pipeline with the stepper cards and gate scoreboard.
  • CLI reference: Fixesmoda fixes / moda fix, including the exit-code contract for agents.
  • Problems — the evidence and feedback endpoints fixes are built on.