Create several eval cases
Adds up to 100 cases to the suite in one call — the bulk form of the single create, and the way to import a suite or convert a repo’s test files without a round trip per case. Every entry needs a title and a non-empty steps array. Cases are validated together and reported individually: a failed entry does not roll back its committed siblings, so the response is 201 even when some entries were refused — read failed rather than branching on the status alone. Send an Idempotency-Key header to make a retry land on the same rows.
Authorizations
MCPJam API key (sk_…). Create one at Settings → API keys. Guest sessions cannot use the API, and API keys cannot manage other API keys.
Headers
Which vocabulary this request and its response speak. Absent means 1, which is byte-for-byte today's contract: the same request fields, the same refusals, the same response projection. 2 is the canonical vocabulary. Any other value is a 400 with code: "VALIDATION_ERROR".
Today it decides one thing: the spelling of an evaluator's policy role. Vocabulary 1 accepts and returns gating; vocabulary 2 accepts both spellings and returns the canonical required. Sending required without the header is a 400, deliberately — vocabulary 1 is not widened to meet vocabulary 2 half way, because a boundary that accepts a spelling it does not announce is one two implementations can disagree about.
A response that varies by vocabulary sends Vary: x-mcpjam-eval-vocabulary.
1, 2 Makes the write retry-safe. A repeat of the same request under the same key lands on the rows the first attempt authored instead of creating a second copy; those entries come back with replayed: true.
256Path Parameters
ID of the hosted project that contains the server.
Eval suite ID, as returned by POST /eval-runs.
Query Parameters
The suite file's own suite.id, when this request is that file syncing itself. A CI-owned suite (see EvalSuiteDetail.managedBy) refuses configuration writes with 409 and details.reason: "CI_OWNED_SUITE_READ_ONLY"; naming the suite's own declared id is how the file writing itself is allowed through. Naming any other id refuses exactly as loudly as naming none, so it is not a capability — omit it for an ordinary edit.
A QUERY PARAMETER on every route that takes it, never a body field. These request bodies are strict, here and on every Inspector that predates the CI-owned lock, so a body field is a 400 against an older deployment — which would break mcpjam cloud eval run --file for anyone whose CLI is newer than their Inspector. A query parameter is read by the deployments that know it and ignored by those that do not, which is the right degradation: an Inspector with no lock has no exception to make.
128Body
Author several cases in one call. Each entry takes the same fields as a single create. The 100-case cap is deliberately smaller than a suite file's 500-case limit, so a maximal file uploads in several calls.
1 - 100 elementsThe suite file's own suite.id, when THIS request is a suite-file sync.
A CI-owned suite (see EvalSuiteDetail.managedBy) refuses configuration writes with 409 and details.reason: "CI_OWNED_SUITE_READ_ONLY". Naming the suite's own declared id is how the file writing itself is allowed through — the platform permits the write only when the id matches, so naming any other id refuses exactly as loudly as naming none. Omit it for ordinary edits.
PREFER THE declaredSuiteId QUERY PARAMETER on this route. This body field still works here, but these request bodies are strict on every Inspector that predates the CI-owned lock, so a body field is a 400 against an older deployment while an unknown query parameter is simply ignored. The MCPJam SDK and CLI send the query parameter.
128What to do with a case whose definition already matches one in the suite. An unrecognized value coerces to block and reports the coercion in the response's duplicatePolicy rather than failing the call.
block, warn, create_anyway Required by warn and create_anyway. Recorded on the case's revision.
1Response
Per-case outcomes. Some entries may have failed; see failed.
A partial outcome by design: the cases in created were written even when failed is non-empty. Both arrays carry the index of the request entry they describe.

