Create an eval suite (author-only, does not run)
Creates a runnable eval suite — the suite record plus its test cases — and responds 201 synchronously, WITHOUT executing anything. Use this to author a suite, then run it later with POST /eval-runs (passing the returned suiteId).
This is distinct from POST /eval-runs, which creates a run and detaches execution, responding 202 with a runId. There is no concurrency cap here (no run is started).
The body uses an ergonomic authoring shape: a suite-level default model (and optional provider) applies to every test unless the test overrides it; provider is derived from a provider/model id when neither is supplied. Each test’s case body is an ordered steps array (prompt / toolCall / interact / assert).
Guest callers are denied (suite creation is a write).
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 Path Parameters
ID of the hosted project that contains the server.
Body
Author-only suite-create body. A suite-level default model (and optional provider) applies to every test unless the test overrides it.
Suite name.
1Servers (by canonical project ID) the suite's cases run against.
1Suite-level default model id (e.g. anthropic/claude-haiku-4.5). Used for any test that omits model.
1Test cases to create in the suite. The object is CLOSED: an unknown key is a VALIDATION_ERROR, never a silently dropped field. repetitions, passThreshold and kind are per-case policy fields this surface cannot author — set them through POST /v1/projects/{projectId}/eval-suites/{suiteId}/cases.
1 - 100 elementsOptional display names, parallel to serverIds.
Clients (hosts) to attach the suite to, in attach order. A suite with no attached client reports none wherever it is listed, and a run has no host to select. Same shape as the PATCH hosts field.
Optional suite-level default provider. When omitted, the provider is derived from a provider/model id.
The floor a run must clear, as a PERCENT in [0, 100] — 80 means 80%. minimumPassRatePercent is the canonical spelling (the unit is in the name); minimumPassRate is the deprecated alias for it. Send exactly one. THE NAME DISAMBIGUATES THE UNIT: a value in (0, 1) is accepted on minimumPassRatePercent, where it unambiguously means a sub-1% floor the evaluator can act on, and REJECTED on the bare minimumPassRate, where 0.8 cannot be told apart from a fraction sent by mistake and would silently make the gate unfailable. Neither field ever reinterprets a value. A per-case passThreshold IS a fraction; this suite/run floor is not.
- Option 1
- Option 2
Accepted for forward-compat; not persisted today (no-op).
Response
The suite was created.
Per-case create outcomes. Partial failures don't abort the suite; an all-failed new suite is rejected with VALIDATION_ERROR.
The servers attached to the suite. name is present when supplied.
The clients (hosts) attached to the suite at create time. Empty when none were named.

