# List Contributor Network benchmark results

```http
GET /api/public/v1/contributor-network/benchmarks
```

**Scope**: `contributor-network.read`.

Lists completed public results produced by configured Contributor Network benchmark activities. This read endpoint never starts, retries, or consumes quota for a benchmark. An activity can stop scheduling new work while retaining its historical results.

Benchmark support is activity-, Competition-, and item-kind-specific. Results from different activities are not necessarily comparable, even when they use similarly named metrics. Filter by `activityId` when constructing a leaderboard or comparison.

## Current public activity

| Field | Value |
| :--- | :--- |
| `activityId` | `CN-BMK-001` |
| Competition | [Mathematics Distillation Stage 1](../competitions/mathematics-distillation-stage1.md) |
| `kind` | `cheatsheet` |
| `problemSet` | `hard3` |
| Models | `llama-3.3-70b-instruct`, `gpt-oss-120b` |
| Scheduling state | Archived after the April 20, 2026 deadline; historical completed results remain readable. |

This contract covers the Stage 1 cheatsheet activity only. Support for a Contributor Network item kind does not imply that benchmark results are available for that kind.

## Query parameters

| Parameter | Type, requirement, default, and meaning |
| :--- | :--- |
| `activityId` | **Optional string.** Exact, case-sensitive public benchmark activity ID. Use this filter for a comparable cohort. |
| `competitionId` | **Optional string.** Exact, case-sensitive Competition ID. The Competition must be publicly visible and expose the selected benchmark activity. |
| `problemSet` | **Optional string.** Exact problem-set ID declared by a selected public activity. |
| `modelId` | **Optional string.** Exact model ID declared by a selected public activity. Restricts each result's `perModel` array and recalculates its aggregate fields from that model. |
| `minAvgAccuracy` | **Optional number.** Minimum average accuracy from `0` through `1`. |
| `search` | **Optional string.** Trimmed, non-empty text of at most 200 characters. Case-insensitive substring match against the public author display name or public team number. |
| `sortBy` | **Optional string.** `avgAccuracy` (default), `publishedAt`, or `scoredTotal`. |
| `sortDirection` | **Optional string.** `desc` (default) or `asc`. |
| `cursor` | **Optional string.** Opaque cursor returned by the preceding page. |
| `limit` | **Optional integer.** Page size from `1` through `100`; defaults to `25`. |

Filters combine by intersection. `modelId` is applied before `minAvgAccuracy`, sorting, and pagination. A problem set or model that is not declared by any selected public activity returns `422 RESOURCE_FIELD_INVALID`; a supported value with no matching completed result returns an empty page.

Unknown query parameters, repeated single-value parameters, blank filter values, and invalid parameter combinations return `422 RESOURCE_FIELD_INVALID`.

## Visibility and result state

Only a completed result attached to an active public item is listed. The item's owning Competition must remain publicly visible and must expose the result's benchmark activity.

Withdrawing an item removes its result from this API without deleting the retained benchmark record. Archiving an activity stops new scheduling but does not hide its existing completed public results. No matches return an empty page. `503 BENCHMARK_RESULTS_UNAVAILABLE` means results are temporarily unavailable; retry the read later.

## Ordering and pagination

The primary order comes from `sortBy` and `sortDirection`. Ties use `completedAt` and then `resultId` in the same direction. Filters and visibility rules apply to the complete matching collection before pagination.

The opaque cursor is bound to the API key owner, this endpoint, all normalized filters, and the complete ordering. Reusing it with a different request context returns `400 MALFORMED_BODY`. Pagination is not a frozen snapshot: newly published or withdrawn results can affect later pages, so long-running clients should de-duplicate by `resultId`. See [Pagination](../../pagination.md).

## Example request

```bash
curl "https://api.sair.foundation/api/public/v1/contributor-network/benchmarks?activityId=CN-BMK-001&sortBy=avgAccuracy&sortDirection=desc&limit=25" \
  -H "Authorization: Bearer $SAIR_API_KEY"
```

## Response

Returns `200 OK` with:

| Field | Type | Description |
| :--- | :--- | :--- |
| `items` | `BenchmarkSummary[]` | Visible benchmark result summaries. |
| `nextCursor` | string \| null | Cursor for the next page, or `null` after the final page. |

### Benchmark summary

| Field | Type | Description |
| :--- | :--- | :--- |
| `resultId` | string | Stable, opaque benchmark-result ID. |
| `activityId` | string | Frozen public activity that produced this result. |
| `itemId` | string | Active Contributor Network item evaluated by the activity. |
| `publicCode` | string | Item's immutable human-shareable code. |
| `competitionId` | string | Competition that owns both the item and activity. |
| `kind` | string | Item discriminator. It is `cheatsheet` for `CN-BMK-001`. |
| `title` | string | Immutable item title. |
| `author.sairId` | string | Public SAIR account ID. |
| `author.displayName` | string | Public display name snapshotted with the item. |
| `author.avatarUrl` | string \| null | Public avatar URL, or `null` when absent. |
| `team` | object \| null | Public team snapshot for the activity, currently `{ teamNumber }`, or `null` when the result is not team-associated. |
| `status` | string | Always `done` in this collection. |
| `problemSet` | string | Frozen problem-set ID evaluated by the activity. |
| `perModel` | [`BenchmarkModelSummary[]`](#per-model-summary) | Metrics in the activity's configured model order, or the single selected model when `modelId` is present. |
| `avgAccuracy` | number | Arithmetic mean of the returned models' `accuracy` values, from `0` through `1`. |
| `scoredCorrect` | integer | Sum of `scoredCorrect` across the returned models. |
| `scoredTotal` | integer | Sum of `scoredTotal` across the returned models. |
| `viewerHasFavorited` | boolean | Whether the API key owner currently favorites the item. |
| `publishedAt` | string | ISO 8601 UTC item-publication time. |
| `completedAt` | string | Immutable ISO 8601 UTC time when this benchmark result became complete. |

### Per-model summary

| Field | Type | Description |
| :--- | :--- | :--- |
| `modelId` | string | Exact frozen model ID. |
| `accuracy` | number | Raw accuracy from `0` through `1`. |
| `scoredCorrect` | integer | Correct scored cases. |
| `scoredTotal` | integer | Total scored cases. |
| `f1Score` | number \| null | F1 score when declared by the activity. |
| `parseSuccessRate` | number \| null | Parse-success rate from `0` through `1` when declared by the activity. |
| `totalCostUsd` | number \| null | Total measured model cost in USD when declared by the activity. |
| `meanElapsedSeconds` | number \| null | Mean measured elapsed seconds per case when declared by the activity. |

The activity definition determines which nullable metrics it publishes. `CN-BMK-001` publishes cost and elapsed-time metrics for both configured models. If a completed result cannot supply the required metrics, the request returns `500 BENCHMARK_RESULT_CORRUPT`. Do not interpret this error as a zero score or an empty result.

Successful responses use `Content-Type: application/json` and `Cache-Control: private, no-store` because `viewerHasFavorited` and item visibility can change.

## Errors

| HTTP | Code | When |
| :---: | :--- | :--- |
| `400` | `MALFORMED_BODY` | The cursor is invalid or `limit` is outside its allowed range. |
| `404` | `NOT_FOUND` | A requested activity or Competition is unavailable, or the Competition does not expose that public benchmark activity. |
| `422` | `RESOURCE_FIELD_INVALID` | A filter, sort, unknown parameter, repeated parameter, or parameter combination is invalid. |
| `500` | `BENCHMARK_RESULT_CORRUPT` | A selected completed result does not satisfy its frozen activity schema. |
| `503` | `BENCHMARK_RESULTS_UNAVAILABLE` | Benchmark results are temporarily unavailable. |

See [Errors](../../errors.md) for shared errors.
