---
title: "Generate a dataset from scratch"
method: POST
path: "/api/v1/datasets/invent"
tags: ["invent"]
---

# Generate a dataset from scratch

`POST /api/v1/datasets/invent`

## Request

- The document declares no server URL.
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/adaptionlabs/apis/adaption-api/docs/api/v1/datasets/invent/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates a dataset and starts generating it. Describe the data either by taxonomy — `domains` and/or `subdomains` — or in your own words with `dataset_prompt`: when neither taxonomy field is given, the domains and subdomains are inferred from the prompt. Explicit taxonomy is authoritative and disables that inference. If the prompt cannot be mapped onto the catalog (or inference is unavailable), the request is rejected with `400` asking for explicit `domains`/`subdomains` — it is never widened to every domain. Returns immediately — poll `GET /datasets/{id}` for the status and `GET /datasets/{id}/download` once it reports `succeeded`. Set `estimate: true` to price a request without generating anything.

## Request body

- CreateInventedDatasetDto
  - `name` string: Display name for the invented dataset.
  - `training_type` 'instruction_dataset' | 'preference_pairs': Shape of the generated data — the same field and values as `datasets.adapt`. `instruction_dataset` produces prompt/completion rows; `preference_pairs` produces ranked completion pairs. Note this is the shape of the DATA, not the training method (elsewhere `training_type` means LoRA vs full fine-tuning). Defaults to `instruction_dataset`. The download carries the generated text in `enhanced_prompt` / `enhanced_completion`; `original_*` are null, since invented data has no source rows it was derived from.
  - `domains` string[]: Domain codes to generate from, e.g. `medical`. Optional: omit it and the domains come from the parents of your `subdomains`, or — when `subdomains` is omitted too — are inferred from `dataset_prompt`. When you do supply it, it is authoritative: inference is skipped, and a subdomain naming a domain that is not listed here is rejected rather than silently added. Retrieve the valid codes from `GET /datasets/invent/domains`.
  - `subdomains` string[]: Narrow generation to specific subdomains, as `domain.subdomain` codes e.g. `medical.symptoms_diagnosis`. Qualified by their domain because a bare code can belong to more than one (`wildlife` sits under both agriculture and animal nature). Requested domains with no subdomain listed here are generated across all of theirs. Optional: with neither this nor `domains`, the taxonomy is inferred from `dataset_prompt`. Supplying it disables that inference. Retrieve the valid codes from `GET /datasets/invent/domains`.
  - `rows` integer, required: Number of rows to generate, subject to your plan’s per-launch row cap. Treat it as a target: the delivered count can land slightly either side of it, so read `row_count` on the finished dataset for what was actually produced.
  - `translate` PublicTranslateTargetsDto
    - `languages` string[], required: Target languages, as ISO 639-1 codes. Each sampled row gains one translated row per language. Unsupported codes are rejected with a sample of the supported ones.
    - `sample_rate` number, required: Fraction of rows translated into each language. At 0.25 with two languages, 1,000 rows become 1,500.
  - `localize` PublicLocalizeTargetsDto
    - `pairs` PublicCountryLanguagePairDto[], required: Target country/language pairs. Each sampled row gains one row localized to each pair — translated into the language and adapted to that country’s conventions. Unsupported combinations are rejected.
      - `country` string, required: ISO 3166-1 alpha-2 country code.
      - `language` string, required: Language code, as ISO 639-1 — optionally with a script subtag. Supported pairs include codes that are not two letters (`zh-Hant` for Taiwan, `yue` for Hong Kong), so the length is not pinned at two here. Membership is decided against the supported-pair list, which names an unsupported entry in its own 400.
    - `sample_rate` number, required: Fraction of rows localized to each pair. At 0.25 with one pair, 1,000 rows become 1,250.
  - `language_expansion` PublicLanguageExpansionSpecDto
    - `type` 'translate' | 'localize', required: Expansion mode. `translate` produces one new row variant per target language; `localize` produces one new row variant per country/language pair.
    - `languages` string[]: Target language codes (required when type=translate, forbidden when type=localize). Mostly ISO 639-1 two-letter codes such as `es`, with three-letter codes where no two-letter code exists (`fil`, `yue`) and script-tagged codes for Chinese (`zh-Hans`, `zh-Hant`). Matching is case-insensitive, and bare `zh` resolves to `zh-Hans`. Validated against the supported language list at request time; unknown values return 400 with a sample of supported codes.
    - `pairs` PublicCountryLanguagePairDto[]: Country/language pairs (required when type=localize, forbidden when type=translate). Each pair is validated against the supported country/language pair list at request time.
      - `country` string, required: ISO 3166-1 alpha-2 country code.
      - `language` string, required: Language code, as ISO 639-1 — optionally with a script subtag. Supported pairs include codes that are not two letters (`zh-Hant` for Taiwan, `yue` for Hong Kong), so the length is not pinned at two here. Membership is decided against the supported-pair list, which names an unsupported entry in its own 400.
    - `sample_rate` number, required: Fraction (0.01–1) of input rows that are expanded per target. Output rows ≈ input × (1 + sample_rate × target_count). Required. Credits are billed on the expanded output row count.
  - `dataset_prompt` string: Free-text description of the data you want, in your own words — the wizard shows this as "Dataset Details". Drives the semantic search that selects rows, so a specific prompt yields more relevant data, and it is woven into the generation instructions. Written for you from your domain selections when omitted. When `domains` and `subdomains` are both omitted this is required, and the domains and subdomains are inferred from it; if none can be inferred the request is rejected with `400` asking for explicit `domains`/`subdomains` rather than generating across every domain.
  - `prompt` string: Deprecated alias for `dataset_prompt`, kept for existing clients. Use `dataset_prompt` in new code. `prompt` will be removed in a future release.
  - `estimate` boolean: Price the request without creating or charging anything. Mirrors `datasets.adapt` — the response carries the same fields either way, with the dataset fields null when this is set.
  - `idempotency_key` string: Client-supplied key making retries safe. Repeating a request with the same key returns the original dataset instead of generating again.

## Response `200`

Generation has started, or — with `estimate: true` — the price of running it.

- PublicInventedDatasetDto
  - `estimate` boolean, required: True when this response priced the request without running it.
  - `id` string, nullable, required: Dataset id, or null on an estimate. Pass it straight to `finetune_jobs.create` or `autoscientist.create` once the status is `succeeded`.
  - `name` string, required: Display name, echoed from the request or the default applied for you.
  - `training_type` 'instruction_dataset' | 'preference_pairs', required: Shape of the generated data, echoed from the request.
  - `domains` string[], required: Domain codes the generation covers, echoed from the request — including any inferred from `subdomains`.
  - `subdomains` string[], required: Subdomain codes the generation is narrowed to, if any.
  - `rows` integer, nullable, required: Number of rows requested.
  - `status` 'pending' | 'running' | 'awaiting_input' | 'succeeded' | 'failed', nullable, required: Lifecycle status, or null on an estimate. A fresh generation is always `running`; poll `GET /datasets/{dataset_id}` until it reports `succeeded` or `failed`.
  - `created_at` string, date-time, nullable, required: When the dataset was created, or null on an estimate.
  - `estimated_credits` number, required: Credits this generation consumes. Billed on the post-expansion row count, so a translated request quotes above its `rows`. Invent pricing is still provisional, so treat the figure as indicative.
  - `available_credits` number, required: Credits currently available to your team.

## Changes

- **2026-11-03** `d4cf908c19a0`: 3 info
  - added the new optional request property `allOf[#/components/schemas/CreateInventedDatasetDto]/localize`
  - added the new optional request property `allOf[#/components/schemas/CreateInventedDatasetDto]/translate`
  - request property `allOf[#/components/schemas/CreateInventedDatasetDto]/language_expansion` deprecated
- **2026-09-15** `f4d1edd8f3d1`: 3 info
  - added the new optional request property `allOf[#/components/schemas/CreateInventedDatasetDto]/dataset_prompt`
  - added `subschema #3, subschema #4` to the request body `anyOf` list
  - request property `allOf[#/components/schemas/CreateInventedDatasetDto]/prompt` deprecated

[Operation history](https://skmtc.dev/adaptionlabs/apis/adaption-api/changes/api/v1/datasets/invent/post.md)

---

[API](https://skmtc.dev/adaptionlabs/apis/adaption-api.md) - [All operations](https://skmtc.dev/adaptionlabs/apis/adaption-api/llms.txt) - [OpenAPI document](https://skmtc.dev/adaptionlabs/apis/adaption-api/revisions/d4cf908c19a0?raw)
