---
title: "Curate a dataset item from a generation"
method: POST
path: "/v1/projects/{project_id}/datasets/{dataset_id}/items/from-generation"
tags: ["Evaluations"]
---

# Curate a dataset item from a generation

`POST /v1/projects/{project_id}/datasets/{dataset_id}/items/from-generation`

## Request

- Base URL: `https://api.naturali.ai`
- URL: `https://api.naturali.ai/v1/projects/{project_id}/datasets/{dataset_id}/items/from-generation`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://api.naturali.ai/authorize`, token URL `https://api.naturali.ai/token`, scopes: `mcp:access`)

Promotes a real, completed generation into a test case: its input messages become the item's `input`, and its own answer becomes `expected_output` unless you supply one. Use it to build an evaluation set out of production traffic rather than hand-authoring fixtures.

The item is a **copy**, not a view. It keeps working after the source generation's content is purged, and `source_generation_id` goes null if that generation is deleted — a purge can never quietly stop a suite from being runnable.

Requires both `evaluations:CreateDataset` and `generations:GetGeneration`: the call copies content out of a generation, so a principal that may not read that generation may not curate it either.

Only a **completed** generation can be promoted (`409 GENERATION_NOT_COMPLETED`), and only while its content is still available: an agent or project running with `trace_content_mode: none` never stored the input, and a purged or expired generation no longer has it (`409 GENERATION_CONTENT_UNAVAILABLE`). Generations that predate input recording answer the same way.

## Path parameters

- `dataset_id` string, required

## Request body

- object
  - `generation_id` string, required: The completed generation to promote. Must belong to the same project as the dataset.
  - `expected_output` string, nullable: Reference answer. Omit to use the generation's own answer; pass `null` to store the item with no reference answer.
  - `metadata` NullableMetadataBag, nullable: A `MetadataBag` on a request field where `null` is meaningful: a full-replacement update that clears the bag. A record whose bag is unset leaves the field out.

## Response `201`

Dataset item created from the generation

- DatasetItem
  - `id` string
  - `dataset_id` string
  - `input` object[]: Messages replayed verbatim as the generation's input
    - `role` string, required
    - `content` string, required: Message content — a string, or AI SDK content parts
  - `expected_output` string, nullable
  - `metadata` MetadataBag: Caller-owned annotations on a resource, stored as the object they were written as: the types a value was written with are the types a read returns, so a filter can ask an ordering question about a number. Unlike other body fields, keys are stored and returned verbatim in the casing supplied — they are not converted between snake_case and camelCase. No key is reserved, and that is the point: every piece of state the platform owns lives in its own typed column, so nothing written here reaches platform state. The platform never reads the bag — it is not an IAM context, not a policy input and not part of a prompt — which is what separates it from a tag bag.
  - `source_generation_id` string, nullable: The generation this item was curated from. A curated item is a deliberate fixture: erasing the source generation neither deletes nor mutates it.
  - `created_at` string, date-time
  - `updated_at` string, date-time

## Other responses

- `400`: Bad request (generation_id missing, or the generation belongs to a different project than the dataset)
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Dataset or generation not found
- `409`: The generation has not completed, its content was never stored or has been purged, or the project's `storage_bytes` quota is exceeded (`QUOTA_STORAGE_EXCEEDED`; delete stored content or raise the quota — no `Retry-After` is sent, since no window reset clears a stored total)

---

[API](https://skmtc.dev/naturali/apis/naturali-ai-api.md) · [All operations](https://skmtc.dev/naturali/apis/naturali-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/naturali/apis/naturali-ai-api/revisions/e4905b78f422?raw)
