---
title: "Score Function Against (input, expected) Pairs"
method: POST
path: "/v3/eval/score"
tags: ["Function Accuracy"]
---

# Score Function Against (input, expected) Pairs

`POST /v3/eval/score`

**Score a function against a list of (input, expected) pairs.**

Submits a batch of `(input, expected)` pairs, runs the named function
over each input, and returns per-pair + aggregate accuracy metrics
comparing the function's actual output to the provided expected JSON.

Scoring runs asynchronously. The response carries a `scoreRunID`;
poll `GET /v3/eval/score/{scoreRunID}` until `status` is one of
`completed`, `error`, or `cancelled`.

This request says only *what to extract*. How the output is compared against the
expected value happens on the GET, recomputed from stored JSON each time.

## Request body

- EvalScoreRequestV3 — Request body for `POST /v3/eval/score`. Scores inputs against the named function. The inputs come from exactly one of two sources — provide either `pairs` (inline) or `datasetID` (a saved Golden Data Set), not both. The request carries no comparison configuration. A run is the extraction — the part that costs model calls. Comparing the output against the expected value is a pure function of two stored JSON values, so every knob that shapes it lives on `GET /v3/eval/score/{scoreRunID}` and can be changed without re-running.
  - `functionName` string, required — Name of the function to score. Must be of type extract, transform, or analyze.
  - `functionVersionNum` integer — Optional version number to score against. P0: only the function's current version is accepted; passing a different version returns 422.
  - `pairs` EvalScorePairV3[] — Inline `(input, expected)` pairs to score, up to 1000 per request. Mutually exclusive with `datasetID`; provide exactly one.
    - `input` FileInput, required — A single file input with base64-encoded content. When using the Bem CLI, use `@path/to/file` in the `inputContent` field to automatically read and base64-encode the file: `--input.single-file '{"inputContent": "@file.pdf", "inputType": "pdf"}' --wait`
      - `inputType` 'csv' | 'docx' | 'email' | 'heic' | 'html' | 'jfif' | 'jpeg' | 'json' | 'heif' | 'm4a' | 'mov' | 'mp3' | 'mp4' | 'pdf' | 'png' | 'pptx' | 'text' | 'wav' | 'webp' | 'xls' | 'xlsx' | 'xml', required — The input type of the content you're sending for transformation. `jfif` is accepted as an alias for `jpeg` — JFIF is the same format under a different extension — and is normalized to `jpeg`, so responses and webhooks report `jpeg` for a JFIF upload. The undeclared alias `jpg` behaves the same way.
      - `inputContent` string, byte, required — Base64-encoded file content. In the Bem CLI, use `@path/to/file` to embed file contents automatically.
    - `expected` unknown, required
  - `datasetID` string — A saved Golden Data Set (`gds_…`) to score against. Mutually exclusive with `pairs`; provide exactly one. Its input / corrected / schema columns are resolved by column role. When it carries a `schema`-role column, scoring types each row against that ground-truth schema instead of the function's own schema — so results hold up as functions/schemas evolve.

## Response `202`

The request has been accepted for processing, but processing has not yet completed.

- EvalScoreCreateResponseV3 — Returned by `POST /v3/eval/score`.
  - `scoreRunID` string, required — Run identifier. Use with `GET /v3/eval/score/{scoreRunID}`.
  - `status` 'pending' | 'initializing' | 'running' | 'completed' | 'error' | 'cancelled', required — Status values for an eval-score run.

## Other responses

- `400` — The server could not understand the request due to invalid syntax.

---

[API](https://skmtc.dev/bem-team/apis/bem-api.md) · [All operations](https://skmtc.dev/bem-team/apis/bem-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/bem-team/bem-api/revisions/a6e4624117c6/schema)
