---
title: "Start Evaluation Suite Runs"
method: POST
path: "/projects/{project_id}/evaluation-suites/{suite_id}/runs"
tags: ["projects"]
---

# Start Evaluation Suite Runs

`POST /projects/{project_id}/evaluation-suites/{suite_id}/runs`

Create append-only Evaluation Suite runs and dispatch existing evaluators.

Args:
    project_id: Owning project.
    suite_id: Pinned Evaluation Suite to execute.
    request: Project models and optional case cap.
    http_request: Incoming request, used to resolve a run key's approved
        plan (ENG-7005).
    auth: Authenticated requester.

Returns:
    Pending run records, one for each selected model.

Raises:
    HTTPException: If suite/model ownership or scorer compatibility is invalid.

## Path parameters

- `project_id` string, required
- `suite_id` string, required

## Request body

- EvaluationSuiteRunCreate — Run one project Evaluation Suite against one or more selected models.
  - `model_ids` string[], required
  - `max_examples` integer, nullable — Optional execution cap. Omit to run every pinned case. Reviewed catalogue splits exceed 10,000 cases, so this field has no upper bound; dispatch still refuses unbounded model fan-out.
  - `cls_threshold` number, nullable — Optional decision threshold for the multi-label classification head (GLiNER2 cls_threshold). Only valid for classification Evaluation Suites; rejected for every other task_type. Must be in [0.0, 1.0] inclusive, matching coerce_cls_threshold's own range check -- 0.0 returns every label, 1.0 falls back to argmax, both meaningful.
  - `sweep_cls_thresholds` number[], nullable — Optional multi-label classification decision thresholds to score for free from this run's own inference pass (ENG-6584). Only valid for classification Evaluation Suites; rejected for every other task_type. Each candidate must be >= 0.5, the floor every inference call runs at today, and <= 1.0. Results land in the completed run's own metrics as 'threshold_sweep' and 'threshold_sweep_best'. Independent of cls_threshold: that field pins the single threshold this run is scored and recorded at, this field additionally sweeps a grid of candidates from the same inference pass -- use it to find a winner cheaply, then a second run with cls_threshold=<winner> to record it durably.
  - `experiment_id` string, nullable — Project-scoped experiment requesting this run.

## Response `200`

Successful Response

- EvaluationSuiteRunResponse[]
  - `id` string, required
  - `suite_id` string, required
  - `project_id` string, required
  - `model_id` string, required
  - `status` 'awaiting_scoring' | 'cancelled' | 'complete' | 'failed' | 'pending' | 'running', required
  - `max_examples` integer, nullable, required
  - `scorer_snapshot` JsonObjectOutput, required
  - `comparison_group` string, nullable, required — Scorer id, version, and behaviour digest. Runs without the same non-null value must not be ranked or compared.
  - `metrics` JsonObjectOutput, required
  - `error_message` string, nullable, required
  - `created_at` string, date-time, required
  - `started_at` string, date-time, nullable, required
  - `lease_expires_at` string, date-time, nullable, required
  - `scoring_expires_at` string, date-time, nullable, required
  - `completed_at` string, date-time, nullable, required

## Other responses

- `404` — Project or Evaluation Suite not found.
- `422` — Validation Error

## Changes

- **2026-09-24** `1cffaad2a921` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/pioneer/apis/brain-api/changes/projects/:project_id/evaluation-suites/:suite_id/runs/post.md)

---

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