## Add localized rows to a dataset

**post** `/api/v1/datasets/{dataset_id}/localize`

Adapts a sample of this dataset’s rows to each country/language pair — translating the text and matching that country’s conventions — and returns the result as a new dataset, leaving this one unchanged. The new dataset carries this dataset’s rows alongside the localized ones. Poll GET /datasets/{dataset_id}/status on the returned id until it reaches `succeeded`. To translate into a language without targeting a country, use POST /datasets/{dataset_id}/translate. Set estimate=true to price the request without starting a run.

### Path Parameters

- `dataset_id: string`

### Body Parameters

- `sample_rate: number`

  Fraction of this dataset’s rows to expand, per target. At 0.25 with two targets, a 1,000-row dataset gains 500 rows and the new dataset holds 1,500.

- `estimate: optional boolean`

  When true, validates the request and returns the estimated credit cost without starting a run or creating a dataset.

- `idempotency_key: optional string`

  Opaque key that makes a retried request safe. A second request carrying the same key returns the dataset the first one created instead of starting and charging for a second run.

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

  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`

    ISO 3166-1 alpha-2 country code.

  - `language: string`

    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.

### Returns

- `dataset_id: string`

  The expanded dataset. It carries this dataset’s rows plus the new ones, and is ready to download once its status reaches `succeeded`. Null for an estimate, which creates nothing.

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

  Status of the expanded dataset at the moment this response was sent, in the same vocabulary GET /datasets/{dataset_id}/status reports. Poll that endpoint until it reaches `succeeded` or `failed`. An idempotent replay of a finished run returns its terminal status here.

  - `"pending"`

  - `"running"`

  - `"awaiting_input"`

  - `"succeeded"`

  - `"failed"`

- `estimated_credits_consumed: number`

  Credits this run consumes, charged against the rows it adds. Zero on an idempotent replay: the earlier run reserved the credits, and this call charges nothing.

- `estimate: boolean`

  Whether this was an estimate-only request (no run started).

- `estimated_new_rows: number`

  Rows this run adds, which is what the credit cost is charged against. Zero on an idempotent replay, which adds none.

### Example

```http
curl https://api.prod.adaptionlabs.ai/api/v1/datasets/$DATASET_ID/localize \
    -H 'Content-Type: application/json' \
    -H "Authorization: Bearer $ADAPTION_API_KEY" \
    -d '{
          "sample_rate": 0.25,
          "pairs": [
            {
              "country": "ES",
              "language": "ca"
            }
          ]
        }'
```

#### Response

```json
{
  "dataset_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "running",
  "estimated_credits_consumed": 5,
  "estimate": true,
  "estimated_new_rows": 500
}
```
