## Generate a dataset from scratch

**post** `/api/v1/datasets/invent`

Creates a dataset and starts generating it from your domain selections. Returns immediately — poll `GET /datasets/{id}` for the status and `GET /datasets/{id}/download` once it reports `succeeded`. Set Set `estimate: true` to price a request without generating anything.

### Body Parameters

- `name: optional string`

  Display name for the invented dataset.

- `training_type: optional "instruction_dataset" or "preference_pairs"`

  Shape of the generated data — the same field and values as `datasets.run`. `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.

  - `"instruction_dataset"`

  - `"preference_pairs"`

- `domains: optional array of string`

  Domain codes to generate from, e.g. `medical`. Supply at least one of `domains` or `subdomains` — omit this and the domains are inferred from the parents of your `subdomains`. When you do supply it, it is authoritative: 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: optional array of 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. Supply at least one of `domains` or `subdomains`. Retrieve the valid codes from `GET /datasets/invent/domains`.

- `rows: number`

  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.

- `language_expansion: optional object { type, languages, pairs, sample_rate }`

  Optionally translate or localize the generated rows into further languages. Credits are billed on the POST-expansion row count, so setting this quotes and charges above `rows`. `sample_rate` (0-1) is the share of rows expanded.

  - `type: "translate" or "localize"`

    Expansion mode. `translate` produces one new row variant per target language; `localize` produces one new row variant per country/language pair.

    - `"translate"`

    - `"localize"`

  - `languages: optional array of string`

    Target ISO 639-1 language codes (required when type=translate, forbidden when type=localize). Validated against the supported language list at request time; unknown values return 400 with a sample of supported codes.

  - `pairs: optional array of object { country, language }`

    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`

      ISO 3166-1 alpha-2 country code.

    - `language: string`

      ISO 639-1 language code.

  - `sample_rate: number`

    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.

- `prompt: optional 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.

- `estimate: optional boolean`

  Price the request without creating or charging anything. Mirrors `datasets.run` — the response carries the same fields either way, with the dataset fields null when this is set.

- `idempotency_key: optional string`

  Client-supplied key making retries safe. Repeating a request with the same key returns the original dataset instead of generating again.

### Returns

- `estimate: boolean`

  True when this response priced the request without running it.

- `id: string`

  Dataset id, or null on an estimate. Pass it straight to `finetune_jobs.create` or `autoscientist.create` once the status is `succeeded`.

- `name: string`

  Display name, echoed from the request or the default applied for you.

- `training_type: "instruction_dataset" or "preference_pairs"`

  Shape of the generated data, echoed from the request.

  - `"instruction_dataset"`

  - `"preference_pairs"`

- `domains: array of string`

  Domain codes the generation covers, echoed from the request — including any inferred from `subdomains`.

- `subdomains: array of string`

  Subdomain codes the generation is narrowed to, if any.

- `rows: number`

  Number of rows requested.

- `status: "pending" or "running" or "awaiting_input" or 2 more`

  Lifecycle status, or null on an estimate. A fresh generation is always `running`; poll `GET /datasets/{dataset_id}` until it reports `succeeded` or `failed`.

  - `"pending"`

  - `"running"`

  - `"awaiting_input"`

  - `"succeeded"`

  - `"failed"`

- `created_at: string`

  When the dataset was created, or null on an estimate.

- `estimated_credits: number`

  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`

  Credits currently available to your team.

### Example

```http
curl https://api.prod.adaptionlabs.ai/api/v1/datasets/invent \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ADAPTION_API_KEY" \
    -d '{
          "name": "Medical Q&A dataset",
          "domains": [
            "medical",
            "personal_finance"
          ],
          "subdomains": [
            "medical.symptoms_diagnosis",
            "medical.preventive_care"
          ],
          "rows": 1000,
          "prompt": "Patient-facing answers to cardiology questions, plain language, no jargon"
        }'
```

#### Response

```json
{
  "estimate": false,
  "id": "3f1b9c62-6f3e-4a1e-9a5c-0b7d2f8e4a10",
  "name": "Clinical Q&A",
  "training_type": "instruction_dataset",
  "domains": [
    "medical"
  ],
  "subdomains": [
    "medical.symptoms_diagnosis"
  ],
  "rows": 1000,
  "status": "running",
  "created_at": "2026-08-03T16:12:04.000Z",
  "estimated_credits": 800,
  "available_credits": 5000
}
```
