---
title: "Write a finished authoring job's cases into the suite"
method: POST
path: "/projects/{projectId}/eval-suites/{suiteId}/authoring/{jobId}/commit"
tags: ["Eval runs"]
---

# Write a finished authoring job's cases into the suite

`POST /projects/{projectId}/eval-suites/{suiteId}/authoring/{jobId}/commit`

Writes the job's drafts into the suite. A draft carrying unresolved blocking issues or proposed additions is **skipped** rather than written, and comes back under `skipped` with a `reviewUrl` for finishing it in the app.

A job whose `source` is `markdown` — the in-app upload — is not committable here and answers `404`: those drafts exist so a person decides on them, and an API commit would decide on their behalf.

## Path parameters

- `projectId` string, required
- `suiteId` string, required
- `jobId` string, required

## Request body

- EvalAuthoringCommitRequest
  - `duplicatePolicy` 'block' | 'warn' | 'create_anyway' — How to treat a case that duplicates one already in the suite. Anything but `block` requires `overrideReason`.
  - `overrideReason` string

## Response `200`

The cases written and any the commit skipped, or the job's own status when it finished without committing (failed, cancelled, or still pending at the end of the wait).

- union
  - EvalCaseImported
    - `generationModel` string, required
    - `created` EvalCase[], required
      - `judge` object — Per-case judge override. enabled: false skips goal-completion grading for this case.
        - `enabled` boolean
      - `id` string, required
      - `declaredId` string — The case's effective declared id. Absent on cases authored before declared identity existed.
      - `title` string, required
      - `steps` EvalTestStep[], required — Ordered test steps. A `prompt` step is a model turn; a single model-free `toolCall` step is a render-check; `assert` steps hold the expectations.
        - `id` string, required
        - `kind` 'prompt' | 'toolCall' | 'interact' | 'assert', required
        - `prompt` string — User message (`kind: prompt`).
        - `serverName` string — Server that owns the tool (`kind: toolCall`).
        - `toolName` string — Tool name (`kind: toolCall` / `interact`).
        - `arguments` object — Tool-call arguments (`kind: toolCall`).
        - `action` object — Widget action (`kind: interact`).
        - `assertion` object — The rule an `assert` step checks (`kind: assert`). NOT a narrower spelling of a case's `checks`: this is `WidgetAssertion | Predicate`, and that union is why the field is called an assertion rather than a check. A `Predicate` is evaluated against the PERSISTED transcript, so a stored run can be re-graded against it months later; a `WidgetAssertion` is evaluated against a LIVE DOM and can never be replayed. Calling this a check would promise the replayability only one half of it has.
      - `expectedOutput` string
      - `iterations` integer, required
      - `repetitions` integer — Trials this case runs under per-case grading, overriding the suite default. Absent means the case inherits it. NOT a second spelling of `iterations`: that one is read as a FLOOR (`max(iterations, suite.minimumIterations)`) by a suite decided on suite-wide accuracy, and a per-case-graded case still reports it for compatibility. This one REPLACES the count rather than raising it — a case at 7 runs 7 times under a floor of 3 and 3 times under a default of 3.
      - `passThreshold` number — Fraction of this case's trials that must pass, overriding the suite default. Absent means the case inherits it. Never derived from the suite's `minimumAccuracy`, which is a PERCENT under a different resolver.
      - `isNegative` boolean, required — When true, the case passes if NO tools are called.
      - `scenario` string
      - `intent` string — Optional authored analytics grouping label. Must be already trimmed; absent means unlabelled.
      - `kind` 'capability' | 'regression' — Authored case kind for the simple editor. Absent means the editor derives it from matchOptions.
      - `models` object[], required
        - `model` string, required
        - `provider` string
      - `matchOptions` object — Absent when the case sets none — omitted from the response rather than sent as `null`.
      - `checks` object — Absent when the case sets none — omitted from the response rather than sent as `null`.
        - `mode` 'inherit' | 'replace' | 'extend'
        - `list` EvalAssertion[]
          - union — An SDK assertion reported through UVC. Discovery assertions require complete raw tool declarations; missing evidence is an evaluator error. Observation kinds, including noDeprecatedToolExposed, require role advisory. Structural schema; runtime also validates policy and unique required annotation keys.
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
      - `import` EvalCaseImportClaim — What a converter CLAIMED about one imported case. `exact` is CONVERTER-CLAIMED exact — the converter says it applied a structural mapping rule, cited in `note`. MCPJam has NOT verified semantic equivalence, so user-facing copy must say "claimed exact", never "verified" or "accepted". Claim-only: who approved an approximation, when, and why is a PER-RUN decision frozen on the run (`ImportEligibility.approvedApproximationReceipts`), never stored on the case — an approval that lived on a case would outlive the run it was granted for and the edit that invalidated it. Approval and internal keys are rejected with 400, never stripped.
        - `status` 'exact' | 'approximated' | 'unsupported' | 'unresolved', required — `exact`: the converter claims a 1:1 structural mapping, and must cite it in `note`. `approximated`: behaviour was intentionally approximated; a human must approve it for EVERY run. `unsupported`: the source behaviour cannot currently be represented. `unresolved`: a deterministic reference does not resolve against the live target. A selected `unsupported` or `unresolved` case cannot run.
        - `sourceCaseKey` string — The case's identity in the source system, when it had one.
        - `note` string — Why the status is what it is — the mapping rule cited, or what was lost. REQUIRED when `status` is `exact`.
      - `source` EvalCaseSource — Where an AI-assisted Markdown case was authored from. Provenance only: the file, its hash, and the line range the extractor read, so a reader can trace a case back to its source document. It is not an import claim (see `EvalCaseImportClaim`) and carries no approval semantics.
        - `format` 'markdown', required
        - `method` 'ai', required — How the case was derived from the document. `ai`: an extractor model proposed it and a person reviewed it before it was saved.
        - `fileName` string, required
        - `fileHash` string, required — SHA-256 of the source document, lowercase hex.
        - `excerpt` string, required — The passage the case was extracted from.
        - `startLine` integer, required
        - `endLine` integer, required — Inclusive; never less than `startLine`.
        - `extractorVersion` string, required
      - `createdAt` number, nullable
      - `updatedAt` number, nullable
      - `suppressedSuiteStandardCheckIds` string[] — Stable standard assertion family IDs suppressed from suite defaults. Applies before inherit/extend/replace resolution; explicit case and step assertions are preserved. Omitted updates preserve; [] clears. At most 64 IDs, normalized to unique sorted values.
    - `counts` object, required
      - `normal` integer
      - `negative` integer
    - `skipped` object[] — Cases the commit could not write, each with its reason. They stay on the job rather than being lost.
    - `reviewUrl` string, uri — Opens the app on exactly the skipped drafts. Present only when something was skipped — finishing them there costs nothing, whereas re-sending the document re-authors and re-bills every case in it.
  - EvalAuthoringJobAccepted
    - `jobId` string, required — Poll this job, then commit it.
    - `status` 'pending' | 'completed' | 'failed' | 'cancelled', required
    - `error` string — Why the job stopped. Present only on a failed job.
    - `generationModel` string
    - `created` EvalCase[] — Always empty here — nothing is written until the job is committed.
      - `judge` object — Per-case judge override. enabled: false skips goal-completion grading for this case.
        - `enabled` boolean
      - `id` string, required
      - `declaredId` string — The case's effective declared id. Absent on cases authored before declared identity existed.
      - `title` string, required
      - `steps` EvalTestStep[], required — Ordered test steps. A `prompt` step is a model turn; a single model-free `toolCall` step is a render-check; `assert` steps hold the expectations.
        - `id` string, required
        - `kind` 'prompt' | 'toolCall' | 'interact' | 'assert', required
        - `prompt` string — User message (`kind: prompt`).
        - `serverName` string — Server that owns the tool (`kind: toolCall`).
        - `toolName` string — Tool name (`kind: toolCall` / `interact`).
        - `arguments` object — Tool-call arguments (`kind: toolCall`).
        - `action` object — Widget action (`kind: interact`).
        - `assertion` object — The rule an `assert` step checks (`kind: assert`). NOT a narrower spelling of a case's `checks`: this is `WidgetAssertion | Predicate`, and that union is why the field is called an assertion rather than a check. A `Predicate` is evaluated against the PERSISTED transcript, so a stored run can be re-graded against it months later; a `WidgetAssertion` is evaluated against a LIVE DOM and can never be replayed. Calling this a check would promise the replayability only one half of it has.
      - `expectedOutput` string
      - `iterations` integer, required
      - `repetitions` integer — Trials this case runs under per-case grading, overriding the suite default. Absent means the case inherits it. NOT a second spelling of `iterations`: that one is read as a FLOOR (`max(iterations, suite.minimumIterations)`) by a suite decided on suite-wide accuracy, and a per-case-graded case still reports it for compatibility. This one REPLACES the count rather than raising it — a case at 7 runs 7 times under a floor of 3 and 3 times under a default of 3.
      - `passThreshold` number — Fraction of this case's trials that must pass, overriding the suite default. Absent means the case inherits it. Never derived from the suite's `minimumAccuracy`, which is a PERCENT under a different resolver.
      - `isNegative` boolean, required — When true, the case passes if NO tools are called.
      - `scenario` string
      - `intent` string — Optional authored analytics grouping label. Must be already trimmed; absent means unlabelled.
      - `kind` 'capability' | 'regression' — Authored case kind for the simple editor. Absent means the editor derives it from matchOptions.
      - `models` object[], required
        - `model` string, required
        - `provider` string
      - `matchOptions` object — Absent when the case sets none — omitted from the response rather than sent as `null`.
      - `checks` object — Absent when the case sets none — omitted from the response rather than sent as `null`.
        - `mode` 'inherit' | 'replace' | 'extend'
        - `list` EvalAssertion[]
          - union — An SDK assertion reported through UVC. Discovery assertions require complete raw tool declarations; missing evidence is an evaluator error. Observation kinds, including noDeprecatedToolExposed, require role advisory. Structural schema; runtime also validates policy and unique required annotation keys.
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
            - object
              - …
      - `import` EvalCaseImportClaim — What a converter CLAIMED about one imported case. `exact` is CONVERTER-CLAIMED exact — the converter says it applied a structural mapping rule, cited in `note`. MCPJam has NOT verified semantic equivalence, so user-facing copy must say "claimed exact", never "verified" or "accepted". Claim-only: who approved an approximation, when, and why is a PER-RUN decision frozen on the run (`ImportEligibility.approvedApproximationReceipts`), never stored on the case — an approval that lived on a case would outlive the run it was granted for and the edit that invalidated it. Approval and internal keys are rejected with 400, never stripped.
        - `status` 'exact' | 'approximated' | 'unsupported' | 'unresolved', required — `exact`: the converter claims a 1:1 structural mapping, and must cite it in `note`. `approximated`: behaviour was intentionally approximated; a human must approve it for EVERY run. `unsupported`: the source behaviour cannot currently be represented. `unresolved`: a deterministic reference does not resolve against the live target. A selected `unsupported` or `unresolved` case cannot run.
        - `sourceCaseKey` string — The case's identity in the source system, when it had one.
        - `note` string — Why the status is what it is — the mapping rule cited, or what was lost. REQUIRED when `status` is `exact`.
      - `source` EvalCaseSource — Where an AI-assisted Markdown case was authored from. Provenance only: the file, its hash, and the line range the extractor read, so a reader can trace a case back to its source document. It is not an import claim (see `EvalCaseImportClaim`) and carries no approval semantics.
        - `format` 'markdown', required
        - `method` 'ai', required — How the case was derived from the document. `ai`: an extractor model proposed it and a person reviewed it before it was saved.
        - `fileName` string, required
        - `fileHash` string, required — SHA-256 of the source document, lowercase hex.
        - `excerpt` string, required — The passage the case was extracted from.
        - `startLine` integer, required
        - `endLine` integer, required — Inclusive; never less than `startLine`.
        - `extractorVersion` string, required
      - `createdAt` number, nullable
      - `updatedAt` number, nullable
      - `suppressedSuiteStandardCheckIds` string[] — Stable standard assertion family IDs suppressed from suite defaults. Applies before inherit/extend/replace resolution; explicit case and step assertions are preserved. Omitted updates preserve; [] clears. At most 64 IDs, normalized to unique sorted values.
    - `counts` object
      - `normal` integer
      - `negative` integer

## Other responses

- `400` — Malformed body or parameters.
- `401` — Missing, invalid, revoked, or orphaned key (`UNAUTHORIZED`) — or the **target MCP server** needs an OAuth grant (`OAUTH_REQUIRED`), which is a property of the server, not your key.
- `403` — Key is valid but not allowed to do this.
- `404` — Unknown project, server, or resource.
- `409` — The resource is not in a state that accepts this write — a stale `expectedRevision`, a duplicate name, or an environment that cannot currently be launched. The request was well-formed; re-read the resource and retry.
- `429` — Per-key rate limit exceeded (60 requests/minute sustained, bursts up to 10). Honor `Retry-After` and back off with jitter.
- `500` — Something failed on MCPJam's side.
- `502` — Could not connect to the target MCP server.
- `504` — The target MCP server connected but didn't respond in time.

## Changes

- **2026-09-25** `311db0744979` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/mcpjam/apis/mcpjam-api/changes/projects/:projectId/eval-suites/:suiteId/authoring/:jobId/commit/post.md)

---

[API](https://skmtc.dev/mcpjam/apis/mcpjam-api.md) · [All operations](https://skmtc.dev/mcpjam/apis/mcpjam-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mcpjam/apis/mcpjam-api/revisions/a15a9864fb85?raw)
