---
title: Objetos
url: https://lumean.app/es/developers/docs/objects
locale: es
description: "Esquemas completos de respuestas y peticiones, con campos y ejemplos."
generated: 2026-10-17
spec_version: 0.0.1
---

# Objetos

Esquemas completos de respuestas y peticiones, con campos y ejemplos.

## AiGatewayCatalogModel

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `key` | `string` | obligatorio | То самое имя, которое надо ставить в поле `model` запроса. Оно же единственное принимаемое: гейтвей резолвит его точным совпадением и уже сам подставляет имя модели на стороне поставщика. |
| `name` | `string` | obligatorio |  |
| `family` | `string` | obligatorio |  |
| `kind` | `string` | obligatorio | `chat` \| `image`. Модель `image` зовут через `/v1/images` (или чатом — ответ придёт markdown-картинкой), цена — `price.request`. |
| `description` | `string` — nullable | obligatorio |  |
| `context_window` | `string` | obligatorio |  |
| `max_output_tokens` | `string` | obligatorio |  |
| `capabilities` | `string` | obligatorio |  |
| `pricing_mode` | `string` | obligatorio |  |
| `price` | `object` — nullable | obligatorio | `null` — отпускной нет: ни одна пара не продаёт модель не в минус. Нули здесь обещали бы бесплатную модель. |
| `price.*` | `object` — claves arbitrarias | — |  |
| `billing_available` | `boolean` | obligatorio | Вызываема ли модель платным ключом. `false` при живой модели — она видна ради своего ключа (BYOK), а платный вызов откажет. |
| `byok` | `string` | obligatorio |  |

**Ejemplo**

```json
{
  "key": "string",
  "name": "string",
  "family": "string",
  "kind": "string",
  "description": "string",
  "context_window": "string",
  "max_output_tokens": "string",
  "capabilities": "string",
  "pricing_mode": "string",
  "price": {},
  "billing_available": true,
  "byok": "string"
}
```

## Asset

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `integer` | obligatorio | Internal identifier of the asset. |
| `code` | `string` | obligatorio | Asset code: `LUMC` is the internal currency, `TOKEN` the generation tokens. |
| `kind` | `AssetKind` — `money` · `unit` | obligatorio | Kind of asset: money or consumable units. It decides whether an amount counts as a payment or as quota consumption. |
| `precision` | `integer` | obligatorio | Number of decimal places. **The load-bearing field:** every integer amount in this asset is divided by `10^precision` to obtain the real value. Do not assume the divisor is 100. |
| `name` | `string` | obligatorio | Display name of the asset, in the account language. |
| `deleted_at` | `string` — date-time — nullable | obligatorio | When the asset was retired, ISO 8601. `null` while it is in use. |
| `created_at` | `string` — date-time — nullable | obligatorio | When the asset was created, ISO 8601. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the asset last changed, ISO 8601. |

**Ejemplo**

```json
{
  "id": 1,
  "code": "string",
  "kind": "money",
  "precision": 1,
  "name": "string",
  "deleted_at": "string",
  "created_at": "string",
  "updated_at": "string"
}
```

## BrowseTemplates

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `items` | `array<TemplateItem>` | obligatorio | Contents of the current folder — folders and templates interleaved, in sort order. Tell them apart by `service_key`: only a template has it. |
| `items[].type` | `string` — `template` | obligatorio |  |
| `items[].id` | `string` | obligatorio |  |
| `items[].name` | `string` | obligatorio |  |
| `items[].slug` | `string` | — |  |
| `items[].service_key` | `string` | — |  |
| `items[].service` | `Service \| null` — nullable | — |  |
| `items[].config` | `object \| string` | — |  |
| `items[].is_public` | `string` | — |  |
| `items[].folder_id` | `string` | — |  |
| `items[].created_at` | `string` | obligatorio |  |
| `items[].updated_at` | `string` | obligatorio |  |
| `items[].templates_count` | `string \| integer` | — |  |
| `current_page` | `integer` | obligatorio | Current page number, starting at 1. |
| `last_page` | `integer` | obligatorio | Number of the last page. When it equals `current_page`, there is nothing further. |
| `per_page` | `integer` | obligatorio | How many records fit on a page. |
| `total` | `integer` | obligatorio | How many records the folder holds in total, across all pages. |
| `current_folder` | `object` — nullable | obligatorio | The folder whose contents are shown. `null` means you are at the root. |
| `current_folder.id` | `string` | obligatorio | UUID of the current folder — pass it as `folder_id` to open the folder again. |
| `current_folder.name` | `string` | obligatorio | Name of the current folder. |
| `breadcrumbs` | `array<object>` | obligatorio | The path from the root to the current folder, ancestor first — ready to render as a breadcrumb trail. |
| `breadcrumbs[].id` | `string` — uuid | — | UUID of an ancestor folder — the `folder_id` value that jumps back to that level. |
| `breadcrumbs[].name` | `string` | — | Name of the ancestor folder. |

**Ejemplo**

```json
{
  "items": [
    {
      "type": "template",
      "id": "string",
      "name": "string",
      "slug": "string",
      "service_key": "string",
      "service": {
        "id": 1,
        "code": "string",
        "name": "string",
        "display_name": "string",
        "label": null,
        "payg_access": "string",
        "billing_mode": "subscription",
        "unit_asset_id": 1,
        "unit_asset": {
          "id": null,
          "code": null,
          "kind": null,
          "precision": null,
          "name": null,
          "deleted_at": null,
          "created_at": null,
          "updated_at": null
        },
        "required_entitlement_id": 1,
        "required_entitlement": {
          "id": null,
          "code": null,
          "name": null,
          "metadata": null,
          "is_active": null,
          "created_at": null,
          "updated_at": null,
          "is_unlimited": null
        },
        "units_per_call": 1,
        "units_per_char": 1,
        "units_per_image": 1,
        "units_per_second": 1,
        "min_billable_chars": 1,
        "lumcoin_per_token": 1,
        "lumc_precision": 1,
        "price_lumc_minor": 1,
        "unit_size": 1,
        "uses_money_first_pricing": true,
        "rate_unit": "string",
        "display_category": "string",
        "is_premium": true,
        "display_order": 1,
        "metadata": {},
        "is_active": true,
        "maintenance_mode": true,
        "access_level": "string",
        "maintenance_auto_resume": true,
        "maintenance_started_at": "string",
        "maintenance_note": "string",
        "created_at": "string",
        "updated_at": "string"
      },
      "config": {},
      "is_public": "string",
      "folder_id": "string",
      "created_at": "string",
      "updated_at": "string"
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 1,
  "total": 1,
  "current_folder": {
    "id": "string",
    "name": "string"
  },
  "breadcrumbs": [
    {
      "id": "string",
      "name": "string"
    }
  ]
}
```

## CartesiaVoiceClone

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Clone UUID. Use it in `/voices/cartesia/clones/{voiceClone}/…` paths; it does NOT go into a template — `voice_id` does. |
| `provider` | `string` — `cartesia` | obligatorio | Clone provider — always `cartesia`. |
| `display_name` | `string` | obligatorio | Clone name given at creation. |
| `language` | `string` | obligatorio | Language of the sample (ISO 639-1), or `null` if none was sent. |
| `description` | `string` | obligatorio | Your description of the clone, or `null`. |
| `status` | `string` | obligatorio | Status: `pending` → `cloning` → `ready` or `failed`; `archived` — retired by the owner; `banned` — blocked by a moderator. Only `ready` can be used for narration. |
| `voice_id` | `string` | obligatorio | The Cartesia voice id — the value for `tts_settings.voice_id` of a template with `service_key: cartesia`. Present only for `ready`, otherwise `null`. |
| `attempts` | `integer` | obligatorio | Cloning attempt number: 1 on creation, +1 for every retry. |
| `error` | `object` — nullable | obligatorio | Why the last attempt failed; `null` while there has been no failure. |
| `error.reason` | `string` | obligatorio | Machine-readable failure code: `processing_error`, `max_retries`, `network`, `timeout`, `dispatch_failed`. Retry with `POST /voices/cartesia/clones/{voiceClone}/retry`; if `processing_error` keeps coming back, use a different sample. |
| `error.message` | `string` | obligatorio | Human-readable explanation of the failure, or `null`. Branch on `reason`, not on this text. |
| `created_at` | `string` | obligatorio | When the clone was created. |
| `completed_at` | `string` | obligatorio | When the clone became `ready`; `null` until then. |
| `failed_at` | `string` | obligatorio | When the last attempt failed; `null` if it has not. |
| `banned_at` | `string` | obligatorio | When a moderator banned the clone (`status = banned`); `null` if it is not banned. |
| `ban_reason` | `string` | obligatorio | Reason for the ban given by the moderator, or `null`. A banned clone can be neither used nor archived. |

**Ejemplo**

```json
{
  "id": "string",
  "provider": "cartesia",
  "display_name": "string",
  "language": "string",
  "description": "string",
  "status": "string",
  "voice_id": "string",
  "attempts": 1,
  "error": {
    "reason": "string",
    "message": "string"
  },
  "created_at": "string",
  "completed_at": "string",
  "failed_at": "string",
  "banned_at": "string",
  "ban_reason": "string"
}
```

## CartesiaVoiceCloneStatus

Status of a Cartesia voice clone: `pending` — queued, `cloning` — in progress, `ready` —
done, carries a `voice_id`; `failed` — refused (the reason is in `error`), can be retried;
`archived` — retired by the owner.

`string`: `pending` · `cloning` · `ready` · `failed` · `archived` · `banned`

**Ejemplo**

```json
"pending"
```

## CartesiaVoice

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Internal id of the catalogue entry. Not needed for narration — `voice_id` goes into the template. |
| `voice_id` | `string` | obligatorio | The Cartesia voice id — the value for `tts_settings.voice_id` of a template with `service_key: cartesia`. |
| `name` | `string` | obligatorio | Voice name. |
| `description` | `string` | obligatorio | Voice description from Cartesia, or `null`. |
| `language` | `string` | obligatorio | Voice language (ISO 639-1), or `null`. |
| `gender` | `string` | obligatorio | Voice gender: `masculine`, `feminine`, `gender_neutral`, or `null`. |
| `preview_url` | `string` | obligatorio | Link to a voice preview recording, or `null`. |

**Ejemplo**

```json
{
  "id": "string",
  "voice_id": "string",
  "name": "string",
  "description": "string",
  "language": "string",
  "gender": "string",
  "preview_url": "string"
}
```

## CreateCartesiaVoiceCloneRequest

A new Cartesia voice clone: a base64 sample recording plus consent to use the voice.
Accepted as `application/json`.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `display_name` | `string` — ≤ 128 caracteres | obligatorio | Clone name — visible only to you, up to 128 characters. |
| `reference_audio` | `string` | obligatorio | The voice sample in base64; a data URI (`data:audio/wav;base64,…`) works too. Up to 20 MB once decoded; any common audio format (WAV, MP3 and the like). It should be clean speech by a single person, without music or noise. |
| `language` | `string` — `en` · `ru` · `uk` · `de` · `fr` · `es` · `pt` · `it` · `nl` · `pl` · `sv` · `tr` · `cs` · `sk` · `bg` · `ro` · `hu` · `el` · `fi` · `da` · `no` · `hr` · `ka` · `he` · `ar` · `hi` · `bn` · `ta` · `te` · `gu` · `kn` · `ml` · `mr` · `pa` · `ja` · `ko` · `zh` · `vi` · `th` · `id` · `ms` · `tl` — nullable | — | Language of the sample, an ISO 639-1 code from the list. Omitted — the default language of the worker. |
| `description` | `string` — ≤ 500 caracteres — nullable | — | Your description of the clone, up to 500 characters. |
| `consent_biometric` | `boolean` | — | Consent to processing of biometric data — the voice sample (https://lumean.app/consent/biometric). Recorded in the consent journal together with the clone id. `true` — consent given. |
| `voice_owner` | `string` — `self` · `third_party` — nullable | — | Whose voice is in the sample: `self` — yours, `third_party` — someone else's, and you hold their consent. |
| `consent_confirmed` | `string` | obligatorio | The former checkbox "the voice is yours or you hold the right to use it". Needed only if `consent_biometric: true` is not sent; once consents become mandatory, send `consent_biometric` and `voice_owner` instead. |

**Ejemplo**

```json
{
  "display_name": "Мой голос",
  "reference_audio": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YQAAAAA=",
  "language": "ru",
  "description": "string",
  "consent_biometric": true,
  "voice_owner": "self",
  "consent_confirmed": true
}
```

## CreateFishAudioVoiceCloneRequest

A new Fish Audio voice clone: a base64 sample recording plus consent to use the voice.
Accepted as `application/json`.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `display_name` | `string` — ≤ 128 caracteres | obligatorio | Clone name — visible only to you, up to 128 characters. |
| `reference_audio` | `string` | obligatorio | The voice sample in base64; a data URI (`data:audio/wav;base64,…`) works too. Up to 20 MB once decoded; any common audio format (WAV, MP3 and the like). It should be clean speech by a single person, without music or noise. |
| `language` | `string` — patrón: ^[a-z]{2}$ — nullable | — | A reference label for the clone, a two-letter ISO 639-1 code (`ru`, `en`, …). Fish Audio voices have no language of their own and the label is not sent to the provider. |
| `description` | `string` — ≤ 500 caracteres — nullable | — | Your description of the clone, up to 500 characters. |
| `consent_biometric` | `boolean` | — | Consent to processing of biometric data — the voice sample (https://lumean.app/consent/biometric). Recorded in the consent journal together with the clone id. `true` — consent given. |
| `voice_owner` | `string` — `self` · `third_party` — nullable | — | Whose voice is in the sample: `self` — yours, `third_party` — someone else's, and you hold their consent. |
| `consent_confirmed` | `string` | obligatorio | The former checkbox "the voice is yours or you hold the right to use it". Needed only if `consent_biometric: true` is not sent; once consents become mandatory, send `consent_biometric` and `voice_owner` instead. |

**Ejemplo**

```json
{
  "display_name": "Мой голос",
  "reference_audio": "UklGRiQAAABXQVZFZm10IBAAAAABAAEAQB8AAIA+AAACABAAZGF0YQAAAAA=",
  "language": "ru",
  "description": "string",
  "consent_biometric": true,
  "voice_owner": "self",
  "consent_confirmed": true
}
```

## Entitlement

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `integer` | obligatorio | Internal identifier of the entitlement. |
| `code` | `string` | obligatorio | Entitlement code — a service checks it to decide whether you have access. |
| `name` | `string` | obligatorio | Display name of the entitlement, in the account language. |
| `metadata` | `object` — nullable | obligatorio | Extra attributes of the entitlement. The key set is free-form. |
| `is_active` | `boolean` | obligatorio | Whether the entitlement is active. |
| `created_at` | `string` — date-time — nullable | obligatorio | When the entitlement was created, ISO 8601. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the entitlement last changed, ISO 8601. |
| `is_unlimited` | `boolean` | — | Whether this capability is unlimited under the plan. Present only when the entitlement is returned in a plan context. |

**Ejemplo**

```json
{
  "id": 1,
  "code": "string",
  "name": "string",
  "metadata": {},
  "is_active": true,
  "created_at": "string",
  "updated_at": "string",
  "is_unlimited": true
}
```

## FishAudioVoiceClone

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Clone UUID. Use it in `/voices/fishaudio/clones/{voiceClone}/…` paths; it does NOT go into a template — `voice_id` does. |
| `provider` | `string` — `fishaudio` | obligatorio | Clone provider — always `fishaudio`. |
| `display_name` | `string` | obligatorio | Clone name given at creation. |
| `language` | `string` | obligatorio | Reference language label (ISO 639-1), or `null` if none was sent. It does not affect cloning. |
| `description` | `string` | obligatorio | Your description of the clone, or `null`. |
| `status` | `string` | obligatorio | Status: `pending` → `cloning` → `ready` or `failed`; `archived` — retired by the owner; `banned` — blocked by a moderator. Only `ready` can be used for narration. |
| `voice_id` | `string` | obligatorio | The Fish Audio voice id (a 32-character hex string, not a UUID) — the value for `tts_settings.voice_id` of a template with `service_key: fishaudio`. Present only for `ready`, otherwise `null`. |
| `attempts` | `integer` | obligatorio | Cloning attempt number: 1 on creation, +1 for every retry. |
| `error` | `object` — nullable | obligatorio | Why the last attempt failed; `null` while there has been no failure. |
| `error.reason` | `string` | obligatorio | Machine-readable failure code: `processing_error`, `max_retries`, `network`, `timeout`, `dispatch_failed`, `unbanned` (the clone was unbanned but had no voice). Retry with `POST /voices/fishaudio/clones/{voiceClone}/retry`; if `processing_error` keeps coming back, use a different sample. |
| `error.message` | `string` | obligatorio | Human-readable explanation of the failure, or `null`. Branch on `reason`, not on this text. |
| `created_at` | `string` | obligatorio | When the clone was created. |
| `completed_at` | `string` | obligatorio | When the clone became `ready`; `null` until then. |
| `failed_at` | `string` | obligatorio | When the last attempt failed; `null` if it has not. |
| `banned_at` | `string` | obligatorio | When a moderator banned the clone (`status = banned`); `null` if it is not banned. |
| `ban_reason` | `string` | obligatorio | Reason for the ban given by the moderator, or `null`. A banned clone can be neither used nor archived. |

**Ejemplo**

```json
{
  "id": "string",
  "provider": "fishaudio",
  "display_name": "string",
  "language": "string",
  "description": "string",
  "status": "string",
  "voice_id": "string",
  "attempts": 1,
  "error": {
    "reason": "string",
    "message": "string"
  },
  "created_at": "string",
  "completed_at": "string",
  "failed_at": "string",
  "banned_at": "string",
  "ban_reason": "string"
}
```

## FishAudioVoiceCloneStatus

Status of a Fish Audio voice clone: `pending` — queued, `cloning` — in progress, `ready` —
done, carries a `voice_id`; `failed` — refused (the reason is in `error`), can be retried;
`archived` — retired by the owner; `banned` — blocked by a moderator (the reason is in
`ban_reason`).

`string`: `pending` · `cloning` · `ready` · `failed` · `archived` · `banned`

**Ejemplo**

```json
"pending"
```

## FishAudioVoice

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Internal id of the catalogue entry. Not needed for narration — `voice_id` goes into the template. |
| `voice_id` | `string` | obligatorio | The Fish Audio voice id (a 32-character hex string, not a UUID) — the value for `tts_settings.voice_id` of a template with `service_key: fishaudio`. |
| `name` | `string` | obligatorio | Voice name. |
| `description` | `string` | obligatorio | Voice description from Fish Audio, or `null`. |
| `language` | `string` | obligatorio | Catalogue language the voice was imported under (`ru`, `en`, `es`), or `null`. |
| `languages` | `string \| array<string>` | obligatorio | All languages of the voice according to Fish Audio. |
| `gender` | `string` | obligatorio | Voice gender: `male`, `female`, or `null`. |
| `tags` | `string \| array<string>` | obligatorio | Voice tags at Fish Audio. |
| `author_name` | `string` | obligatorio | Voice author at Fish Audio, or `null`. |
| `task_count` | `integer` | obligatorio | How many times the voice has been used at Fish Audio — a popularity measure; the catalogue is sorted by it. |
| `like_count` | `integer` | obligatorio | Number of likes of the voice at Fish Audio. |
| `preview_url` | `string` | obligatorio | A temporary link (60 minutes) to an MP3 sample of the voice, or `null` while the preview has not been downloaded yet. |

**Ejemplo**

```json
{
  "id": "string",
  "voice_id": "string",
  "name": "string",
  "description": "string",
  "language": "string",
  "languages": "string",
  "gender": "string",
  "tags": "string",
  "author_name": "string",
  "task_count": 1,
  "like_count": 1,
  "preview_url": "string"
}
```

## GetFileUrlRequest

A request for a temporary link to a result file. Fetch the link with a plain `GET`,
without the `X-API-KEY` header.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `path` | `string` | obligatorio | The full file path exactly as it arrived in the order's `result.files[]` or `result.service_files[]`. Do not assemble it by hand — it contains internal segments. |
| `download` | `boolean` | — | When `true`, the link is marked as an attachment: the file is saved under the human-readable order name instead of opening in a browser tab. |
| `number_base` | `integer` — `0` · `1` | — | Where chunk numbering starts in the file name: `1` → the first chunk is "001", `0` → "000". Defaults to `1`. |
| `number_padding` | `integer` — 1..4 | — | Width of the zero-padded chunk number, `1..4`: `3` → "007". Defaults to `3`. Keep it identical to the ZIP archive request, otherwise the same chunk is named differently on its own and inside the archive. |

**Ejemplo**

```json
{
  "path": "storage/42/orders/9f8b2c1a-4d3e-4f5a-8b9c-0d1e2f3a4b5c/result/output.mp3",
  "download": false,
  "number_base": 1,
  "number_padding": 3
}
```

## GiftCodeBatch

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `uuid` | `string` | obligatorio | The batch id. |
| `source` | `string` | obligatorio | Always `reseller` — the batch was issued from the reseller balance. |
| `codes_count` | `string` | obligatorio | How many codes the batch holds. |
| `nominal_total` | `string` | obligatorio | Sum of the code nominals, LMC minor units. |
| `nominal_total_formatted` | `number` | obligatorio | Sum of the nominals, LMC. |
| `cost_total` | `string` | — | How much was charged to the reseller balance (nominals minus the discount), LMC minor units. |
| `cost_total_formatted` | `number` | — | Charged to the reseller balance, LMC. |
| `discount_bps` | `integer` | — | The reseller personal discount at issue time, basis points (1000 = 10%). |
| `codes` | `array<GiftCode>` | — | The batch codes with the FULL `code` value — store them: they are bearer money. |
| `codes[].uuid` | `string` | obligatorio | Code UUID. Use it in the `GET /reseller/codes/{uuid}` and `POST /reseller/codes/{uuid}/cancel` paths. |
| `codes[].code_masked` | `string` | obligatorio | The code with a mask, `LUM-****-****-XXXX`: safe to show in a UI and to write to logs. |
| `codes[].code` | `string` | — | The FULL code value — what the recipient types to redeem it. The reseller public API returns it in the list, on show and on issue. Treat it as a secret: whoever knows the code can redeem it. |
| `codes[].nominal` | `string` | obligatorio | The code’s nominal value in minor LMC units: `real = nominal / 10^currency_asset.precision`. This is how much LMC the redeemer receives. |
| `codes[].nominal_formatted` | `number` | obligatorio | The same nominal value in whole LMC — a number ready to display. |
| `codes[].cost` | `string` | — | What the code cost the reseller after the discount, in minor LMC units. Present only for reseller codes (`source: reseller`). |
| `codes[].cost_formatted` | `number` | — | The same cost in whole LMC. Present only for reseller codes. |
| `codes[].discount_bps` | `integer` | — | The reseller’s discount at the moment of issue, in basis points (`100` = 1%). A later change of the personal discount does not affect this code. Present only for reseller codes. |
| `codes[].source` | `string` | obligatorio |  |
| `codes[].funding` | `string` | obligatorio |  |
| `codes[].status` | `string` | obligatorio |  |
| `codes[].activatable_at` | `string` | obligatorio | The moment from which the code can be redeemed; until then it is frozen. `null` means no restriction. |
| `codes[].redeemed_at` | `string` | obligatorio | When the code was redeemed. `null` until it is. The API never reveals who redeemed it. |
| `codes[].cancelled_at` | `string` | obligatorio | When the reseller cancelled the code. `null` if it was not cancelled. |
| `codes[].created_at` | `string` | obligatorio | When the code was issued. |
| `codes[].currency_asset` | `object` | obligatorio | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `codes[].currency_asset.code` | `string` — `LUMC` | obligatorio | Code of the asset the amounts are expressed in. |
| `codes[].currency_asset.precision` | `integer` | obligatorio | How many decimals LMC has: `real = value / 10^precision`. |
| `created_at` | `string` | obligatorio | When the batch was issued. |
| `currency_asset` | `object` | obligatorio | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `currency_asset.code` | `string` — `LUMC` | obligatorio | Code of the asset the amounts are expressed in. |
| `currency_asset.precision` | `integer` | obligatorio | How many decimals LMC has: `real = value / 10^precision`. |

**Ejemplo**

```json
{
  "uuid": "string",
  "source": "string",
  "codes_count": "string",
  "nominal_total": "string",
  "nominal_total_formatted": 1,
  "cost_total": "string",
  "cost_total_formatted": 1,
  "discount_bps": 1,
  "codes": [
    {
      "uuid": "string",
      "code_masked": "string",
      "code": "string",
      "nominal": "string",
      "nominal_formatted": 1,
      "cost": "string",
      "cost_formatted": 1,
      "discount_bps": 1,
      "source": "string",
      "funding": "string",
      "status": "string",
      "activatable_at": "string",
      "redeemed_at": "string",
      "cancelled_at": "string",
      "created_at": "string",
      "currency_asset": {
        "code": "LUMC",
        "precision": 1
      }
    }
  ],
  "created_at": "string",
  "currency_asset": {
    "code": "LUMC",
    "precision": 1
  }
}
```

## GiftCodeList

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `items` | `array<GiftCode>` | obligatorio | Records on the current page, in the list’s sort order. |
| `items[].uuid` | `string` | obligatorio | Code UUID. Use it in the `GET /reseller/codes/{uuid}` and `POST /reseller/codes/{uuid}/cancel` paths. |
| `items[].code_masked` | `string` | obligatorio | The code with a mask, `LUM-****-****-XXXX`: safe to show in a UI and to write to logs. |
| `items[].code` | `string` | — | The FULL code value — what the recipient types to redeem it. The reseller public API returns it in the list, on show and on issue. Treat it as a secret: whoever knows the code can redeem it. |
| `items[].nominal` | `string` | obligatorio | The code’s nominal value in minor LMC units: `real = nominal / 10^currency_asset.precision`. This is how much LMC the redeemer receives. |
| `items[].nominal_formatted` | `number` | obligatorio | The same nominal value in whole LMC — a number ready to display. |
| `items[].cost` | `string` | — | What the code cost the reseller after the discount, in minor LMC units. Present only for reseller codes (`source: reseller`). |
| `items[].cost_formatted` | `number` | — | The same cost in whole LMC. Present only for reseller codes. |
| `items[].discount_bps` | `integer` | — | The reseller’s discount at the moment of issue, in basis points (`100` = 1%). A later change of the personal discount does not affect this code. Present only for reseller codes. |
| `items[].source` | `string` | obligatorio |  |
| `items[].funding` | `string` | obligatorio |  |
| `items[].status` | `string` | obligatorio |  |
| `items[].activatable_at` | `string` | obligatorio | The moment from which the code can be redeemed; until then it is frozen. `null` means no restriction. |
| `items[].redeemed_at` | `string` | obligatorio | When the code was redeemed. `null` until it is. The API never reveals who redeemed it. |
| `items[].cancelled_at` | `string` | obligatorio | When the reseller cancelled the code. `null` if it was not cancelled. |
| `items[].created_at` | `string` | obligatorio | When the code was issued. |
| `items[].currency_asset` | `object` | obligatorio | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `items[].currency_asset.code` | `string` — `LUMC` | obligatorio | Code of the asset the amounts are expressed in. |
| `items[].currency_asset.precision` | `integer` | obligatorio | How many decimals LMC has: `real = value / 10^precision`. |
| `current_page` | `integer` | obligatorio | Current page number, starting from one. |
| `last_page` | `integer` | obligatorio | Number of the last page. The walk is over once `current_page` equals `last_page`. |
| `per_page` | `integer` | obligatorio | Page size the server applied. |
| `total` | `integer` | obligatorio | Total number of records matching the filter. |

**Ejemplo**

```json
{
  "items": [
    {
      "uuid": "string",
      "code_masked": "string",
      "code": "string",
      "nominal": "string",
      "nominal_formatted": 1,
      "cost": "string",
      "cost_formatted": 1,
      "discount_bps": 1,
      "source": "string",
      "funding": "string",
      "status": "string",
      "activatable_at": "string",
      "redeemed_at": "string",
      "cancelled_at": "string",
      "created_at": "string",
      "currency_asset": {
        "code": "LUMC",
        "precision": 1
      }
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 1,
  "total": 1
}
```

## GiftCode

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `uuid` | `string` | obligatorio | Code UUID. Use it in the `GET /reseller/codes/{uuid}` and `POST /reseller/codes/{uuid}/cancel` paths. |
| `code_masked` | `string` | obligatorio | The code with a mask, `LUM-****-****-XXXX`: safe to show in a UI and to write to logs. |
| `code` | `string` | — | The FULL code value — what the recipient types to redeem it. The reseller public API returns it in the list, on show and on issue. Treat it as a secret: whoever knows the code can redeem it. |
| `nominal` | `string` | obligatorio | The code’s nominal value in minor LMC units: `real = nominal / 10^currency_asset.precision`. This is how much LMC the redeemer receives. |
| `nominal_formatted` | `number` | obligatorio | The same nominal value in whole LMC — a number ready to display. |
| `cost` | `string` | — | What the code cost the reseller after the discount, in minor LMC units. Present only for reseller codes (`source: reseller`). |
| `cost_formatted` | `number` | — | The same cost in whole LMC. Present only for reseller codes. |
| `discount_bps` | `integer` | — | The reseller’s discount at the moment of issue, in basis points (`100` = 1%). A later change of the personal discount does not affect this code. Present only for reseller codes. |
| `source` | `string` | obligatorio |  |
| `funding` | `string` | obligatorio |  |
| `status` | `string` | obligatorio |  |
| `activatable_at` | `string` | obligatorio | The moment from which the code can be redeemed; until then it is frozen. `null` means no restriction. |
| `redeemed_at` | `string` | obligatorio | When the code was redeemed. `null` until it is. The API never reveals who redeemed it. |
| `cancelled_at` | `string` | obligatorio | When the reseller cancelled the code. `null` if it was not cancelled. |
| `created_at` | `string` | obligatorio | When the code was issued. |
| `currency_asset` | `object` | obligatorio | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `currency_asset.code` | `string` — `LUMC` | obligatorio | Code of the asset the amounts are expressed in. |
| `currency_asset.precision` | `integer` | obligatorio | How many decimals LMC has: `real = value / 10^precision`. |

**Ejemplo**

```json
{
  "uuid": "string",
  "code_masked": "string",
  "code": "string",
  "nominal": "string",
  "nominal_formatted": 1,
  "cost": "string",
  "cost_formatted": 1,
  "discount_bps": 1,
  "source": "string",
  "funding": "string",
  "status": "string",
  "activatable_at": "string",
  "redeemed_at": "string",
  "cancelled_at": "string",
  "created_at": "string",
  "currency_asset": {
    "code": "LUMC",
    "precision": 1
  }
}
```

## GiftCodeSource

Where the code came from: bought by a user with money (`purchase`) or issued by a
reseller from their own balance (`reseller`).

`string`: `purchase` · `reseller`

**Ejemplo**

```json
"purchase"
```

## GiftCodeStatus

Gift code status: `active` — issued and awaiting redemption (possibly still frozen
until `activatable_at`); `refunding` — a refund is in progress, redemption and
cancellation are unavailable; `redeemed` — redeemed, the nominal is on the redeemer's
balance; `refunded` — the money went back to the buyer's card; `cancelled` — the
reseller cancelled the code and the cost returned to their balance; `annulled` —
annulled with no refund.

`string`: `active` · `refunding` · `redeemed` · `refunded` · `cancelled` · `annulled`

**Ejemplo**

```json
"active"
```

## IssueGiftCodesRequest

Issuing codes from the reseller balance. The `Idempotency-Key` header is optional but
recommended: with it a network retry cannot issue a second batch.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `nominals` | `array<number>` — mín. elementos: 1, máx. elementos: 1000 | obligatorio | Code nominals in LMC, one number per code: as many codes as elements. Numbers and decimal strings are accepted; a nominal is either one of the presets from `GET /reseller/settings` or between `min_nominal` and `max_nominal`. The number of elements is capped by `limits.max_codes_per_issue` from `GET /reseller`. |

**Ejemplo**

```json
{
  "nominals": [
    100,
    100,
    250
  ]
}
```

## LumVoiceList

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `items` | `array<LumVoice>` | obligatorio | Records on the current page, in the list’s sort order. |
| `items[].id` | `string` | obligatorio | Voice UUID. Put it into a template’s `config.voice_id`; the same value goes into `/voices/{voice}` paths. |
| `items[].display_name` | `string` | obligatorio | Display name of the voice. |
| `items[].description` | `string` | obligatorio | Author’s description of the voice: timbre, delivery, intended use. |
| `items[].gender` | `string` | obligatorio | Voice gender. |
| `items[].accent` | `string` | obligatorio | Accent or regional pronunciation variant. |
| `items[].default_language_code` | `string` | obligatorio | The language the voice defaults to, ISO-639-1. |
| `items[].voice_status` | `string` | obligatorio | Cloning state of the voice. Only a fully prepared voice can be used in orders. |
| `items[].publication_status` | `string` | obligatorio | Publication stage: draft, under review, published. It determines whether the voice appears in the shared catalogue `GET /voices/public`. |
| `items[].allow_usage_in_orders` | `boolean` | obligatorio | Whether the author lets others use the voice. Without this flag the voice is absent from the `GET /voices/public` catalogue, and library entries other users already made for it become unavailable. |
| `items[].preview_generated_at` | `string` — date-time — nullable | obligatorio | When the preview clips were produced, ISO 8601. `null` means there is no preview yet. |
| `items[].created_at` | `string` — date-time — nullable | obligatorio | When the voice was created, ISO 8601. |
| `items[].updated_at` | `string` — date-time — nullable | obligatorio | When the voice last changed, ISO 8601. |
| `items[].tags` | `array<VoiceTag>` | — | Voice tags for search and filtering. The full directory is `GET /voices/tags`. |
| `items[].tags[].id` | `integer` | obligatorio | Internal identifier of the tag. |
| `items[].tags[].code` | `string` | obligatorio | Tag code — the stable value to filter by, unlike the translatable `name`. |
| `items[].tags[].name` | `string` | obligatorio | Tag name in the account language. |
| `items[].tags[].description` | `string` — nullable | obligatorio | Explanation of the tag in the account language, when the author provided one. |
| `items[].tags[].color` | `string` | obligatorio | Tag colour in HEX — a styling hint. |
| `items[].tags[].sort_order` | `integer` | obligatorio | Sort weight within the tag list: lower comes first. |
| `items[].languages` | `array<VoiceLanguage>` | — | Languages the voice has been cloned into, each with its own state. An order is only possible in a language that is ready. |
| `items[].languages[].id` | `integer` | obligatorio | Internal identifier of the voice’s language version. |
| `items[].languages[].language_code` | `string` | obligatorio | Language code, ISO-639-1. It is also the key used in `preview_urls`. |
| `items[].languages[].status` | `string` | obligatorio | Cloning state for this language. Orders are accepted only in a language whose clone is ready. |
| `items[].languages[].reference_duration_ms` | `integer` — nullable | obligatorio | Duration of the reference recording in milliseconds — the clone was trained on it. |
| `items[].languages[].model_version` | `integer` | obligatorio | Version of the trained model. It increments whenever the voice is retrained. |
| `items[].languages[].failure_reason` | `string` — nullable | obligatorio | Why cloning failed. `null` when there was no failure. |
| `items[].languages[].clone_started_at` | `string` — date-time — nullable | obligatorio | When cloning started, ISO 8601. |
| `items[].languages[].clone_completed_at` | `string` — date-time — nullable | obligatorio | When cloning finished, ISO 8601. `null` means it is still running or it failed. |
| `items[].languages[].updated_at` | `string` — date-time — nullable | obligatorio | When the language version last changed, ISO 8601. |
| `items[].preview_urls` | `object` | obligatorio | Preview clips by language: the key is a language code, the value a temporary audio link or `null` when there is no preview for that language. The links live for about a minute. |
| `items[].preview_urls.*` | `string` — claves arbitrarias — nullable | — |  |
| `current_page` | `integer` | obligatorio | Current page number, starting from one. |
| `last_page` | `integer` | obligatorio | Number of the last page. The walk is over once `current_page` equals `last_page`. |
| `per_page` | `integer` | obligatorio | Page size the server applied. |
| `total` | `integer` | obligatorio | Total number of records matching the filter. |

**Ejemplo**

```json
{
  "items": [
    {
      "id": "string",
      "display_name": "string",
      "description": "string",
      "gender": "string",
      "accent": "string",
      "default_language_code": "string",
      "voice_status": "string",
      "publication_status": "string",
      "allow_usage_in_orders": true,
      "preview_generated_at": "string",
      "created_at": "string",
      "updated_at": "string",
      "tags": [
        {
          "id": 1,
          "code": "string",
          "name": "string",
          "description": "string",
          "color": "string",
          "sort_order": 1
        }
      ],
      "languages": [
        {
          "id": 1,
          "language_code": "string",
          "status": "string",
          "reference_duration_ms": 1,
          "model_version": 1,
          "failure_reason": "string",
          "clone_started_at": "string",
          "clone_completed_at": "string",
          "updated_at": "string"
        }
      ],
      "preview_urls": {}
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 1,
  "total": 1
}
```

## LumVoice

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Voice UUID. Put it into a template’s `config.voice_id`; the same value goes into `/voices/{voice}` paths. |
| `display_name` | `string` | obligatorio | Display name of the voice. |
| `description` | `string` | obligatorio | Author’s description of the voice: timbre, delivery, intended use. |
| `gender` | `string` | obligatorio | Voice gender. |
| `accent` | `string` | obligatorio | Accent or regional pronunciation variant. |
| `default_language_code` | `string` | obligatorio | The language the voice defaults to, ISO-639-1. |
| `voice_status` | `string` | obligatorio | Cloning state of the voice. Only a fully prepared voice can be used in orders. |
| `publication_status` | `string` | obligatorio | Publication stage: draft, under review, published. It determines whether the voice appears in the shared catalogue `GET /voices/public`. |
| `allow_usage_in_orders` | `boolean` | obligatorio | Whether the author lets others use the voice. Without this flag the voice is absent from the `GET /voices/public` catalogue, and library entries other users already made for it become unavailable. |
| `preview_generated_at` | `string` — date-time — nullable | obligatorio | When the preview clips were produced, ISO 8601. `null` means there is no preview yet. |
| `created_at` | `string` — date-time — nullable | obligatorio | When the voice was created, ISO 8601. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the voice last changed, ISO 8601. |
| `tags` | `array<VoiceTag>` | — | Voice tags for search and filtering. The full directory is `GET /voices/tags`. |
| `tags[].id` | `integer` | obligatorio | Internal identifier of the tag. |
| `tags[].code` | `string` | obligatorio | Tag code — the stable value to filter by, unlike the translatable `name`. |
| `tags[].name` | `string` | obligatorio | Tag name in the account language. |
| `tags[].description` | `string` — nullable | obligatorio | Explanation of the tag in the account language, when the author provided one. |
| `tags[].color` | `string` | obligatorio | Tag colour in HEX — a styling hint. |
| `tags[].sort_order` | `integer` | obligatorio | Sort weight within the tag list: lower comes first. |
| `languages` | `array<VoiceLanguage>` | — | Languages the voice has been cloned into, each with its own state. An order is only possible in a language that is ready. |
| `languages[].id` | `integer` | obligatorio | Internal identifier of the voice’s language version. |
| `languages[].language_code` | `string` | obligatorio | Language code, ISO-639-1. It is also the key used in `preview_urls`. |
| `languages[].status` | `string` | obligatorio | Cloning state for this language. Orders are accepted only in a language whose clone is ready. |
| `languages[].reference_duration_ms` | `integer` — nullable | obligatorio | Duration of the reference recording in milliseconds — the clone was trained on it. |
| `languages[].model_version` | `integer` | obligatorio | Version of the trained model. It increments whenever the voice is retrained. |
| `languages[].failure_reason` | `string` — nullable | obligatorio | Why cloning failed. `null` when there was no failure. |
| `languages[].clone_started_at` | `string` — date-time — nullable | obligatorio | When cloning started, ISO 8601. |
| `languages[].clone_completed_at` | `string` — date-time — nullable | obligatorio | When cloning finished, ISO 8601. `null` means it is still running or it failed. |
| `languages[].updated_at` | `string` — date-time — nullable | obligatorio | When the language version last changed, ISO 8601. |
| `preview_urls` | `object` | obligatorio | Preview clips by language: the key is a language code, the value a temporary audio link or `null` when there is no preview for that language. The links live for about a minute. |
| `preview_urls.*` | `string` — claves arbitrarias — nullable | — |  |

**Ejemplo**

```json
{
  "id": "string",
  "display_name": "string",
  "description": "string",
  "gender": "string",
  "accent": "string",
  "default_language_code": "string",
  "voice_status": "string",
  "publication_status": "string",
  "allow_usage_in_orders": true,
  "preview_generated_at": "string",
  "created_at": "string",
  "updated_at": "string",
  "tags": [
    {
      "id": 1,
      "code": "string",
      "name": "string",
      "description": "string",
      "color": "string",
      "sort_order": 1
    }
  ],
  "languages": [
    {
      "id": 1,
      "language_code": "string",
      "status": "string",
      "reference_duration_ms": 1,
      "model_version": 1,
      "failure_reason": "string",
      "clone_started_at": "string",
      "clone_completed_at": "string",
      "updated_at": "string"
    }
  ],
  "preview_urls": {}
}
```

## OrderList

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `items` | `array<Order>` | obligatorio | Orders of the current page. |
| `current_page` | `integer` | obligatorio | Current page number, starting from 1. |
| `last_page` | `integer` | obligatorio | Number of the last page. |
| `per_page` | `integer` | obligatorio | Items per page. |
| `total` | `integer` | obligatorio | Total items matching the filter. |

**Ejemplo**

```json
{
  "items": [],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 0
}
```

## OrderItem

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Chunk UUID. Use it in `/orders/{order}/items/{item}/…` paths. |
| `order_id` | `string` | obligatorio | UUID of the order this chunk belongs to. |
| `item_type` | `string` | obligatorio | What the record is: `chunk` is an original fragment, `retry` a free re-run of a failed one, `regeneration` a paid redo of a finished one. Retries and regenerations are separate records sharing the same `chunk_index`: the full attempt history is kept, and the last one is what the result plays. |
| `chunk_index` | `integer` — nullable | obligatorio | Zero-based position of the fragment within the order. It defines the order in which the final file is assembled. |
| `paragraph_index` | `string` | obligatorio | The paragraph this fragment belongs to — filled in only for the original fragments of a paragraph-mode order. It is `null` both in ordinary mode and on retry or regeneration records: those carry no paragraph link of their own and inherit it from the parent fragment via `parent_item_id`. The mode is switched on by the `generation_mode` key in the order's `config_override`. |
| `parent_item_id` | `string` | obligatorio | UUID of the source chunk — present on `retry` and `regeneration` records. `null` on an original chunk. |
| `original_text_length` | `integer` | obligatorio | Length of the text the fragment was created with. It is the ceiling for `text` in `regenerate`. |
| `current_text_length` | `integer` | obligatorio | Length of the fragment’s current text: after a regeneration it differs from `original_text_length`. |
| `price_units` | `integer` | obligatorio | Cost of the fragment in **tokens** — not money. The monetary amount lives on the order itself, in its own `price_units` field (LMC there, tokens here; the names match, the units do not). |
| `consumed_units` | `integer` | obligatorio | How many tokens were actually charged for this fragment. Zero while the fragment is unfinished. |
| `remaining_locked` | `integer` | obligatorio | How many tokens are still reserved for the fragment. Drops to zero once the fragment finishes or is cancelled. |
| `status` | `string` | obligatorio | Fragment state: `pending` waits for a worker, `processing` is in flight, `completed` is done, `failed` hit a technical error, and `policy_flagged` was rejected by the content policy. The difference between the last two dictates the fix: `failed` is cured by retrying as is, whereas `policy_flagged` requires rewording — retrying the same text is rejected again. |
| `result_file` | `object \| string \| null` — nullable | obligatorio | The finished fragment’s file: an absolute path, or a structure carrying path and size. Download it via `POST /storage/url`, same as order files. `null` until the fragment is ready. |
| `duration_ms` | `integer` — nullable | obligatorio | Duration of the produced audio in milliseconds — the length of the recording, not the generation time. `null` for non-audio tasks. |
| `attempt_number` | `integer` | obligatorio | Attempt number for this fragment, starting at 1. It grows with every retry. |
| `can_retry` | `boolean` | obligatorio | Whether a free retry is allowed right now. It already accounts for status, task type and exhausted attempts, so you need not re-check the conditions. |
| `can_regenerate` | `boolean` | obligatorio | Whether a paid regeneration is allowed right now. Available for finished fragments only. |
| `created_at` | `string` — date-time — nullable | obligatorio | When the fragment was created, ISO 8601. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the fragment last changed, ISO 8601. |
| `failure_reason` | `string` — nullable | — | Machine-readable failure reason — present only on `failed` and `policy_flagged`. Everything else gets `null`. |

**Ejemplo**

```json
{
  "id": "string",
  "order_id": "string",
  "item_type": "string",
  "chunk_index": 1,
  "paragraph_index": "string",
  "parent_item_id": "string",
  "original_text_length": 1,
  "current_text_length": 1,
  "price_units": 1,
  "consumed_units": 1,
  "remaining_locked": 1,
  "status": "string",
  "result_file": {},
  "duration_ms": 1,
  "attempt_number": 1,
  "can_retry": true,
  "can_regenerate": true,
  "created_at": "string",
  "updated_at": "string",
  "failure_reason": "string"
}
```

## Order

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Order UUID. Use it in `/orders/{order}/…` paths and when calling `POST /orders/{order}/retry`. |
| `user_id` | `integer` | obligatorio | ID of the order owner. For orders created with an API key this is always the key owner — a key never sees someone else’s order. |
| `name` | `string` | obligatorio | Order name: the downloaded file name and the ZIP archive name are derived from it. |
| `template` | `Template` | — | The template the order was created from. Present only for orders that have a `template_id`; template-less orders (`sfx`/`music` created by `task_type`) omit it. Its `config` holds the settings THIS order runs with: the template configuration at the moment the order was created, with `config_override` applied on top; editing the template later does not change it. In the `GET /orders` list `config` is `null` — the full configuration comes from `GET /orders/{order}`. The template may have been deleted since: it is still shown here, but `GET /templates/{template}` returns `404` and a new order with that `template_id` returns `422`. Orders created before this API version (late September 2026) have no snapshot: their `config` is the current template configuration with `config_override` applied, and editing the template changes it. |
| `template.id` | `string` | obligatorio | Template UUID. Put it into `template_id` when creating an order. |
| `template.user_id` | `integer` | obligatorio | ID of the template owner. |
| `template.slug` | `string` | obligatorio | Short public identifier used for sharing. `null` on a template that was never shared. |
| `template.name` | `string` | obligatorio | Template name — for humans only; it does not affect generation. |
| `template.service_key` | `string` | obligatorio | Code of the service whose schema validates `config`: `elevenlabs`, `lumimg`, and so on. |
| `template.service` | `Service \| null` — nullable | obligatorio | The template’s service for reference: name and pricing, without configuration schemas. `null` means no service with that code exists any more. |
| `template.config` | `object` | obligatorio | Generation settings: voice, model, speed and so on — the set of keys is defined by the service. Look up allowed values in `GET /templates/config-options?service=<code>`; anything outside the schema is rejected with `422`. Inside an order (`template` in `GET /orders/{order}`) this is the order’s own settings — the snapshot taken at creation with `config_override` applied, not the template’s current configuration (for orders created before late September 2026 — the current template configuration with `config_override`). |
| `template.is_public` | `boolean` | obligatorio | Whether the template is published in the shared catalogue. |
| `template.folder_id` | `string` | obligatorio | UUID of the folder holding the template, or `null` for the root. The folder tree is visible in `GET /templates/browse`. |
| `template.created_at` | `string` — date-time — nullable | obligatorio | When the template was created, ISO 8601. |
| `template.updated_at` | `string` — date-time — nullable | obligatorio | When the template last changed, ISO 8601. |
| `template_id` | `string` | obligatorio | UUID of the template used, or `null` when the order was created without one. |
| `task_type` | `TaskType` — `tts` · `image` · `txt2img` · `remix` · `image_edit` · `voice_clone` · `sfx` · `music` · `voice_search` | obligatorio | Task type — it determines what goes into `task_data` and what comes back in `result`. |
| `status` | `OrderStatus` — `created` · `pending` · `in_progress` · `completed` · `result_delivered` · `failed` · `compensated` · `cancelled` · `partially_completed` | obligatorio | Current state of the order. Terminal values are `completed`, `failed`, `cancelled` and `compensated` — there is nothing to poll for after those. `partially_completed` means some chunks succeeded and some failed: the finished files are already downloadable, and the failed fragments can be requeued via `POST /orders/{order}/items/retry-failed`. |
| `price_units` | `integer` | obligatorio | The amount locked for the order, in LMC minor units. Do not display this number as-is: the real value is `price_units / 10^precision`, where `precision` comes from the asset alongside. A display-ready value sits in the neighbouring decimal field. |
| `price_formatted` | `number` — nullable | obligatorio | The same amount as `price_units`, expressed in whole LMC and ready to display. `null` until the cost is settled. |
| `currency_asset` | `Asset` | obligatorio | The amount's asset is always LMC. Its `precision` is what converts minor units into the real value. |
| `currency_asset.id` | `integer` | obligatorio | Internal identifier of the asset. |
| `currency_asset.code` | `string` | obligatorio | Asset code: `LUMC` is the internal currency, `TOKEN` the generation tokens. |
| `currency_asset.kind` | `AssetKind` — `money` · `unit` | obligatorio | Kind of asset: money or consumable units. It decides whether an amount counts as a payment or as quota consumption. |
| `currency_asset.precision` | `integer` | obligatorio | Number of decimal places. **The load-bearing field:** every integer amount in this asset is divided by `10^precision` to obtain the real value. Do not assume the divisor is 100. |
| `currency_asset.name` | `string` | obligatorio | Display name of the asset, in the account language. |
| `currency_asset.deleted_at` | `string` — date-time — nullable | obligatorio | When the asset was retired, ISO 8601. `null` while it is in use. |
| `currency_asset.created_at` | `string` — date-time — nullable | obligatorio | When the asset was created, ISO 8601. |
| `currency_asset.updated_at` | `string` — date-time — nullable | obligatorio | When the asset last changed, ISO 8601. |
| `total_tokens` | `integer` — nullable | obligatorio | The order's full cost in tokens: the original chunks plus every retry and regeneration. This is a quota unit, not money. |
| `total_duration_ms` | `integer` — nullable | obligatorio | Total length of the produced audio in milliseconds. This is the result's duration, not the time spent generating it. |
| `task_data` | `object` — nullable | obligatorio | The task input exactly as the server accepted it: text, references to uploaded files, resolved settings. The set of keys depends on `task_type`. |
| `result` | `object` — nullable | obligatorio | Execution result. `files[]` holds the primary files; `service_files[]` holds auxiliary ones (subtitles `.srt`/`.vtt`/`.lrc`, alignment) for TTS orders. Paths are **absolute** and ready to pass to `POST /storage/url`. `null` while the order is unfinished, and also for a failed order: the public surface does not expose error internals. |
| `created_at` | `string` — date-time — nullable | obligatorio | When the order was created, ISO 8601. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the order last changed, ISO 8601. It advances on every status transition, which makes it a cheap “something happened” signal. |
| `files_expire_at` | `string` — nullable | obligatorio | Retention of the order's files. `files_expire_at` is the deletion moment (`null` when the order has not finished yet, or the files are already gone); `files_expired` means nothing is left to download. |
| `files_expired` | `boolean` | obligatorio | `true` means retention has elapsed and the files are already deleted: no link can be issued, and the order has to be created again. |
| `retention` | `object` | obligatorio | Retention deadlines by file level. For a stitched order the per-fragment tracks are removed earlier than the result itself. |
| `retention.chunks` | `object` | obligatorio | Lifetime of the per-fragment tracks — pause editing, re-stitching and per-fragment regeneration all operate on them. |
| `retention.chunks.expires_at` | `string` | obligatorio | When the per-fragment tracks disappear, ISO 8601. Until then pause editing, re-stitching and per-fragment regeneration remain available. `null` means the order has not finished yet (the countdown has not started) or the fragments are already gone. |
| `retention.chunks.expired` | `boolean` | obligatorio | `true` means the per-fragment tracks are gone: editing and re-stitching are rejected. The finished result may still be available — check `retention.files`. |
| `retention.chunks.expires_early` | `boolean` | obligatorio | `true` means the fragments will disappear before the result (the order is stitched into a separate file). `false` means the fragments are the result, and both levels expire together. |
| `retention.chunks.reason` | `string` — `chunks_purged` · `storage_expired` · `null` — nullable | obligatorio | Why the fragments are unavailable: `chunks_purged` — removed on their own schedule while the result is still there; `storage_expired` — every file of the order is gone. `null` means the fragments are available. |
| `retention.files` | `object` | obligatorio | Lifetime of every file of the order, including the result. Mirrors the top-level `files_expire_at` / `files_expired` fields. |
| `retention.files.expires_at` | `string` — nullable | obligatorio | When every file of the order will be deleted, ISO 8601. The same value as `files_expire_at` — the top-level field is kept for compatibility. |
| `retention.files.expired` | `boolean` | obligatorio | Same as `files_expired`: nothing is left to download. |
| `eta_seconds` | `integer` — nullable | obligatorio | Estimated time remaining, in seconds — present only while the order is running. `null` once it is finished, and before it starts. |
| `eta_at` | `string` — date-time — nullable | obligatorio | Expected completion moment, ISO 8601 — the same forecast as `eta_seconds`, expressed as an absolute time. |
| `completed_chunks` | `integer` — nullable | obligatorio | How many source chunks are already finished. Retries and regenerations are excluded — counting them would push progress past 100%. |
| `total_chunks` | `integer` — nullable | obligatorio | How many source chunks the order has in total. Zero means the split has not happened yet. |
| `progress_percent` | `integer` — nullable | obligatorio | Completion percentage, 0–100 — derived from `completed_chunks` and `total_chunks`, so there is no need to compute it yourself. |
| `stitching` | `boolean` | obligatorio | `true` means the audio is being stitched and the result is not final yet. This also happens with `status = completed`: after a fragment is regenerated the final track is rebuilt, and until stitching ends `result` points to the previous track. Download the result once `stitching = false`. |
| `paragraphs` | `array<object>` — nullable | obligatorio | Per-paragraph summary: index, fragment count, aggregate status and progress. `null` means the order uses ordinary mode — use `items[]` instead. To get paragraphs, create the order with `config_override.generation_mode = paragraph` (see that field for details). |
| `paragraphs[].paragraph_index` | `integer` | obligatorio | Zero-based index of the paragraph. |
| `paragraphs[].chunks_count` | `integer \| number` | obligatorio | How many chunks the paragraph was split into. |
| `paragraphs[].completed_chunks` | `string \| integer` | obligatorio | How many of the paragraph’s chunks are already finished. |
| `paragraphs[].status` | `string` | obligatorio | Aggregate status of the paragraph: derived from its chunks’ statuses rather than stored separately. It uses its own, shorter vocabulary: `pending`, `in_progress`, `failed`, `completed` — a chunk blocked by moderation also reads as `failed`. Only the original chunks count, so a successful retry of a failed fragment does NOT change the paragraph status: check the fragment itself in `items[]`. |
| `paragraphs[].progress_percent` | `integer` | obligatorio | Paragraph completion percentage, 0–100. |
| `paragraphs[].result_file` | `string` — nullable | obligatorio | The whole paragraph stitched into one audio file: an absolute path, or a structure carrying path and size. Download it via `POST /storage/url`, same as the other order files. `null` means two different things depending on `chunks_count`: with `chunks_count = 1` the paragraph has no file of its own and never will — the paragraph *is* that single fragment, so take its `result_file` from `items[]` under the same `paragraph_index`; with `chunks_count > 1` the stitch has not happened yet — a multi-chunk paragraph gets its file ONLY after stitching, never in advance. |
| `items` | `array<OrderItem>` | — | The order’s chunks. Present in the detailed `GET /orders/{order}` response; the list endpoint `GET /orders` omits the field — use `GET /orders/{order}/items` instead. |
| `items[].id` | `string` | obligatorio | Chunk UUID. Use it in `/orders/{order}/items/{item}/…` paths. |
| `items[].order_id` | `string` | obligatorio | UUID of the order this chunk belongs to. |
| `items[].item_type` | `string` | obligatorio | What the record is: `chunk` is an original fragment, `retry` a free re-run of a failed one, `regeneration` a paid redo of a finished one. Retries and regenerations are separate records sharing the same `chunk_index`: the full attempt history is kept, and the last one is what the result plays. |
| `items[].chunk_index` | `integer` — nullable | obligatorio | Zero-based position of the fragment within the order. It defines the order in which the final file is assembled. |
| `items[].paragraph_index` | `string` | obligatorio | The paragraph this fragment belongs to — filled in only for the original fragments of a paragraph-mode order. It is `null` both in ordinary mode and on retry or regeneration records: those carry no paragraph link of their own and inherit it from the parent fragment via `parent_item_id`. The mode is switched on by the `generation_mode` key in the order's `config_override`. |
| `items[].parent_item_id` | `string` | obligatorio | UUID of the source chunk — present on `retry` and `regeneration` records. `null` on an original chunk. |
| `items[].original_text_length` | `integer` | obligatorio | Length of the text the fragment was created with. It is the ceiling for `text` in `regenerate`. |
| `items[].current_text_length` | `integer` | obligatorio | Length of the fragment’s current text: after a regeneration it differs from `original_text_length`. |
| `items[].price_units` | `integer` | obligatorio | Cost of the fragment in **tokens** — not money. The monetary amount lives on the order itself, in its own `price_units` field (LMC there, tokens here; the names match, the units do not). |
| `items[].consumed_units` | `integer` | obligatorio | How many tokens were actually charged for this fragment. Zero while the fragment is unfinished. |
| `items[].remaining_locked` | `integer` | obligatorio | How many tokens are still reserved for the fragment. Drops to zero once the fragment finishes or is cancelled. |
| `items[].status` | `string` | obligatorio | Fragment state: `pending` waits for a worker, `processing` is in flight, `completed` is done, `failed` hit a technical error, and `policy_flagged` was rejected by the content policy. The difference between the last two dictates the fix: `failed` is cured by retrying as is, whereas `policy_flagged` requires rewording — retrying the same text is rejected again. |
| `items[].result_file` | `object \| string \| null` — nullable | obligatorio | The finished fragment’s file: an absolute path, or a structure carrying path and size. Download it via `POST /storage/url`, same as order files. `null` until the fragment is ready. |
| `items[].duration_ms` | `integer` — nullable | obligatorio | Duration of the produced audio in milliseconds — the length of the recording, not the generation time. `null` for non-audio tasks. |
| `items[].attempt_number` | `integer` | obligatorio | Attempt number for this fragment, starting at 1. It grows with every retry. |
| `items[].can_retry` | `boolean` | obligatorio | Whether a free retry is allowed right now. It already accounts for status, task type and exhausted attempts, so you need not re-check the conditions. |
| `items[].can_regenerate` | `boolean` | obligatorio | Whether a paid regeneration is allowed right now. Available for finished fragments only. |
| `items[].created_at` | `string` — date-time — nullable | obligatorio | When the fragment was created, ISO 8601. |
| `items[].updated_at` | `string` — date-time — nullable | obligatorio | When the fragment last changed, ISO 8601. |
| `items[].failure_reason` | `string` — nullable | — | Machine-readable failure reason — present only on `failed` and `policy_flagged`. Everything else gets `null`. |
| `tokens_from_quota` | `integer` — nullable | — | How many of the spent tokens were covered by the subscription quota. `null` means the quota covered nothing. |
| `tokens_from_payg` | `integer` — nullable | — | How many tokens were paid for out of the LMC balance, beyond the quota. `null` means there was no top-up. |
| `tokens_spent` | `integer` — nullable | — | The sum of the two fields above: how many tokens were charged for the order (quota + top-up). Orders covered by an unlimited subscription and free versions are excluded — an unlimited order has `null` here; the generated volume is `total_tokens`. Retries are excluded — they are not billed again. |
| `queue_position` | `integer` — nullable | — | Position in the queue — only for voice-search tasks (`voice_search`), which are processed one at a time. Other task types omit the field. |
| `queue_wait_seconds` | `integer` — nullable | — | Estimated wait in the voice-search queue, in seconds. An estimate, not a promise — recomputed on every response. |

**Ejemplo**

```json
{
  "id": "string",
  "user_id": 1,
  "name": "string",
  "template": {
    "id": "string",
    "user_id": 1,
    "slug": "string",
    "name": "string",
    "service_key": "string",
    "service": {
      "id": 1,
      "code": "string",
      "name": "string",
      "display_name": "string",
      "label": [
        "string"
      ],
      "payg_access": "string",
      "billing_mode": "subscription",
      "unit_asset_id": 1,
      "unit_asset": {
        "id": 1,
        "code": "string",
        "kind": "money",
        "precision": 1,
        "name": "string",
        "deleted_at": "string",
        "created_at": "string",
        "updated_at": "string"
      },
      "required_entitlement_id": 1,
      "required_entitlement": {
        "id": 1,
        "code": "string",
        "name": "string",
        "metadata": {},
        "is_active": true,
        "created_at": "string",
        "updated_at": "string",
        "is_unlimited": true
      },
      "units_per_call": 1,
      "units_per_char": 1,
      "units_per_image": 1,
      "units_per_second": 1,
      "min_billable_chars": 1,
      "lumcoin_per_token": 1,
      "lumc_precision": 1,
      "price_lumc_minor": 1,
      "unit_size": 1,
      "uses_money_first_pricing": true,
      "rate_unit": "string",
      "display_category": "string",
      "is_premium": true,
      "display_order": 1,
      "metadata": {},
      "is_active": true,
      "maintenance_mode": true,
      "access_level": "string",
      "maintenance_auto_resume": true,
      "maintenance_started_at": "string",
      "maintenance_note": "string",
      "created_at": "string",
      "updated_at": "string"
    },
    "config": {},
    "is_public": true,
    "folder_id": "string",
    "created_at": "string",
    "updated_at": "string"
  },
  "template_id": "string",
  "task_type": "tts",
  "status": "created",
  "price_units": 1,
  "price_formatted": 1,
  "currency_asset": {
    "id": 1,
    "code": "string",
    "kind": "money",
    "precision": 1,
    "name": "string",
    "deleted_at": "string",
    "created_at": "string",
    "updated_at": "string"
  },
  "total_tokens": 1,
  "total_duration_ms": 1,
  "task_data": {},
  "result": {},
  "created_at": "string",
  "updated_at": "string",
  "files_expire_at": "string",
  "files_expired": true,
  "retention": {
    "chunks": {
      "expires_at": "string",
      "expired": true,
      "expires_early": true,
      "reason": "chunks_purged"
    },
    "files": {
      "expires_at": "string",
      "expired": true
    }
  },
  "eta_seconds": 1,
  "eta_at": "string",
  "completed_chunks": 1,
  "total_chunks": 1,
  "progress_percent": 1,
  "stitching": true,
  "paragraphs": [
    {
      "paragraph_index": 1,
      "chunks_count": 1,
      "completed_chunks": "string",
      "status": "string",
      "progress_percent": 1,
      "result_file": "string"
    }
  ],
  "items": [
    {
      "id": "string",
      "order_id": "string",
      "item_type": "string",
      "chunk_index": 1,
      "paragraph_index": "string",
      "parent_item_id": "string",
      "original_text_length": 1,
      "current_text_length": 1,
      "price_units": 1,
      "consumed_units": 1,
      "remaining_locked": 1,
      "status": "string",
      "result_file": {},
      "duration_ms": 1,
      "attempt_number": 1,
      "can_retry": true,
      "can_regenerate": true,
      "created_at": "string",
      "updated_at": "string",
      "failure_reason": "string"
    }
  ],
  "tokens_from_quota": 1,
  "tokens_from_payg": 1,
  "tokens_spent": 1,
  "queue_position": 1,
  "queue_wait_seconds": 1
}
```

## OrderStatus

`string`: `created` · `pending` · `in_progress` · `completed` · `result_delivered` · `failed` · `compensated` · `cancelled` · `partially_completed`

**Ejemplo**

```json
"created"
```

## PreviewChunksRequest

Chunk-preview parameters — a dry-run of the text-to-chunks split and its cost, without
creating an order. Free of charge, does not spend the key's token quota.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `template_id` | `string` — uuid | obligatorio |  |
| `task_type` | `string` — nullable | — |  |
| `input_text` | `string` | obligatorio |  |
| `previous_preview_id` | `string` — nullable | — | The `preview_id` of a prior preview response, for incremental re-preview: only the edited neighborhood is recomputed. Works for sync texts (≤50,000 characters); for larger ones the edit still goes through a full async recalculation. If it has expired, just omit it — you get a full recalculation instead. |
| `text_hash` | `string` — patrón: ^[a-f0-9]{64}$ — nullable | — | Not required for `POST` — the server computes the hash itself from `input_text`. Send it only if you already know it for some other reason; it is otherwise ignored here (used by `GET /orders/chunks/preview` for the preflight lookup instead). |
| `generation_mode` | `string` — `default` · `paragraph` — nullable | — | Generation mode — the same value accepted by `config_override.generation_mode` when creating an order. `paragraph` splits the text on blank lines first, and each paragraph becomes its own generation unit (see `POST /orders` for the full explanation). Omitted — a continuous split, the previous behavior. |
| `config_override` | `object` | — | Generation settings on top of the template config — the same JSON object you will send to `POST /orders`. Settings that affect the split apply to the preview exactly as to the order; keys the service does not declare are dropped. Omitted — the split follows the template config alone. |

**Ejemplo**

```json
{
  "template_id": "string",
  "task_type": "string",
  "input_text": "string",
  "previous_preview_id": "string",
  "text_hash": "string",
  "generation_mode": "default",
  "config_override": {}
}
```

## PublicVoiceList

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `items` | `array<LumVoice>` | obligatorio | Records on the current page, in the list’s sort order. |
| `items[].id` | `string` | obligatorio | Voice UUID. Put it into a template’s `config.voice_id`; the same value goes into `/voices/{voice}` paths. |
| `items[].display_name` | `string` | obligatorio | Display name of the voice. |
| `items[].description` | `string` | obligatorio | Author’s description of the voice: timbre, delivery, intended use. |
| `items[].gender` | `string` | obligatorio | Voice gender. |
| `items[].accent` | `string` | obligatorio | Accent or regional pronunciation variant. |
| `items[].default_language_code` | `string` | obligatorio | The language the voice defaults to, ISO-639-1. |
| `items[].voice_status` | `string` | obligatorio | Cloning state of the voice. Only a fully prepared voice can be used in orders. |
| `items[].publication_status` | `string` | obligatorio | Publication stage: draft, under review, published. It determines whether the voice appears in the shared catalogue `GET /voices/public`. |
| `items[].allow_usage_in_orders` | `boolean` | obligatorio | Whether the author lets others use the voice. Without this flag the voice is absent from the `GET /voices/public` catalogue, and library entries other users already made for it become unavailable. |
| `items[].preview_generated_at` | `string` — date-time — nullable | obligatorio | When the preview clips were produced, ISO 8601. `null` means there is no preview yet. |
| `items[].created_at` | `string` — date-time — nullable | obligatorio | When the voice was created, ISO 8601. |
| `items[].updated_at` | `string` — date-time — nullable | obligatorio | When the voice last changed, ISO 8601. |
| `items[].tags` | `array<VoiceTag>` | — | Voice tags for search and filtering. The full directory is `GET /voices/tags`. |
| `items[].tags[].id` | `integer` | obligatorio | Internal identifier of the tag. |
| `items[].tags[].code` | `string` | obligatorio | Tag code — the stable value to filter by, unlike the translatable `name`. |
| `items[].tags[].name` | `string` | obligatorio | Tag name in the account language. |
| `items[].tags[].description` | `string` — nullable | obligatorio | Explanation of the tag in the account language, when the author provided one. |
| `items[].tags[].color` | `string` | obligatorio | Tag colour in HEX — a styling hint. |
| `items[].tags[].sort_order` | `integer` | obligatorio | Sort weight within the tag list: lower comes first. |
| `items[].languages` | `array<VoiceLanguage>` | — | Languages the voice has been cloned into, each with its own state. An order is only possible in a language that is ready. |
| `items[].languages[].id` | `integer` | obligatorio | Internal identifier of the voice’s language version. |
| `items[].languages[].language_code` | `string` | obligatorio | Language code, ISO-639-1. It is also the key used in `preview_urls`. |
| `items[].languages[].status` | `string` | obligatorio | Cloning state for this language. Orders are accepted only in a language whose clone is ready. |
| `items[].languages[].reference_duration_ms` | `integer` — nullable | obligatorio | Duration of the reference recording in milliseconds — the clone was trained on it. |
| `items[].languages[].model_version` | `integer` | obligatorio | Version of the trained model. It increments whenever the voice is retrained. |
| `items[].languages[].failure_reason` | `string` — nullable | obligatorio | Why cloning failed. `null` when there was no failure. |
| `items[].languages[].clone_started_at` | `string` — date-time — nullable | obligatorio | When cloning started, ISO 8601. |
| `items[].languages[].clone_completed_at` | `string` — date-time — nullable | obligatorio | When cloning finished, ISO 8601. `null` means it is still running or it failed. |
| `items[].languages[].updated_at` | `string` — date-time — nullable | obligatorio | When the language version last changed, ISO 8601. |
| `items[].preview_urls` | `object` | obligatorio | Preview clips by language: the key is a language code, the value a temporary audio link or `null` when there is no preview for that language. The links live for about a minute. |
| `items[].preview_urls.*` | `string` — claves arbitrarias — nullable | — |  |
| `current_page` | `integer` | obligatorio | Current page number, starting from one. |
| `last_page` | `integer` | obligatorio | Number of the last page. The walk is over once `current_page` equals `last_page`. |
| `per_page` | `integer` | obligatorio | Page size the server applied. |
| `total` | `integer` | obligatorio | Total number of records matching the filter. |

**Ejemplo**

```json
{
  "items": [
    {
      "id": "string",
      "display_name": "string",
      "description": "string",
      "gender": "string",
      "accent": "string",
      "default_language_code": "string",
      "voice_status": "string",
      "publication_status": "string",
      "allow_usage_in_orders": true,
      "preview_generated_at": "string",
      "created_at": "string",
      "updated_at": "string",
      "tags": [
        {
          "id": 1,
          "code": "string",
          "name": "string",
          "description": "string",
          "color": "string",
          "sort_order": 1
        }
      ],
      "languages": [
        {
          "id": 1,
          "language_code": "string",
          "status": "string",
          "reference_duration_ms": 1,
          "model_version": 1,
          "failure_reason": "string",
          "clone_started_at": "string",
          "clone_completed_at": "string",
          "updated_at": "string"
        }
      ],
      "preview_urls": {}
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 1,
  "total": 1
}
```

## RegenerateOrderItemRequest

Parameters for regenerating a completed order fragment.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `text` | `string` — ≤ 50000 caracteres | obligatorio | New text for a completed chunk — **required**. Regenerating an already finished fragment is billed as a new generation (the key's token quota is checked first, `429` on excess). |

**Ejemplo**

```json
{
  "text": "Новая редакция фрагмента."
}
```

## ResellerProfile

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Reseller ID. |
| `status` | `string` | obligatorio |  |
| `discount_bps` | `string` | obligatorio | The reseller’s personal discount on issued codes, in basis points: `100` = 1%. It sets the price of a code: `cost = nominal × (1 − discount_bps / 10000)`. |
| `blocked_reason` | `string` | obligatorio | Why the account is blocked. `null` while it is not blocked. |
| `approved_at` | `string` | obligatorio | When the reseller application was approved. |
| `limits` | `string` | — | Limits — personal when an administrator set them, otherwise the shared defaults: `max_topup_rub` is the ceiling of a single top-up in roubles, `max_codes_per_issue` is how many codes one `POST /reseller/codes` request may issue. |
| `balance` | `object` | — | The account balance. Every amount comes as a pair: in minor LMC units (`available`, `held`, `debt`, …; `real = value / 10^currency_asset.precision`) and `<name>_formatted`, the same amount in whole LMC. `available` is what sits on the account, `held` is frozen, `debt` is owed to the platform (the next top-up repays it), `spendable` is what can actually be spent on issuing (`available` minus the debt). |
| `balance.*` | `integer \| number` — claves arbitrarias | — |  |
| `currency_asset` | `object` | obligatorio | The currency of the amounts in the response — LMC. Use `precision` to convert amounts in minor units into whole LMC. |
| `currency_asset.code` | `string` — `LUMC` | obligatorio | Code of the asset the amounts are expressed in. |
| `currency_asset.precision` | `integer` | obligatorio | How many decimals LMC has: `real = value / 10^precision`. |

**Ejemplo**

```json
{
  "id": "string",
  "status": "string",
  "discount_bps": "string",
  "blocked_reason": "string",
  "approved_at": "string",
  "limits": "string",
  "balance": {},
  "currency_asset": {
    "code": "LUMC",
    "precision": 1
  }
}
```

## RetryOrderItemRequest

Parameters for retrying a failed order fragment.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `text` | `string` — ≤ 50000 caracteres — nullable | — | Corrected chunk text. If omitted, the chunk is retried with its previous text. For a `policy_flagged` chunk (content rejected by the provider) **the same text will be rejected again** — send a rephrased one. The current text is available at `GET /orders/{order}/items/{item}/text`. |

**Ejemplo**

```json
{
  "text": "Переформулированный фрагмент текста."
}
```

## RetryOrderRequest

Billing confirmation for the repeat order. An empty body is the normal path; these
fields only matter after a `402` response in the fallback mode with explicit confirmation.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `confirm_payg_topup` | `boolean` — nullable | — | Consent to a pay-as-you-go top-up for the new order — only in the fallback mode with explicit confirmation (otherwise ignored). Same semantics as `POST /orders`: valid only together with a fresh `quote_token` from a `402` response. |
| `quote_token` | `string` — nullable | — | The top-up quote from this request's `402` response (fallback mode only). Lives about 60 seconds. |

**Ejemplo**

```json
{
  "confirm_payg_topup": false,
  "quote_token": "string"
}
```

## Service

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `integer` | obligatorio | Internal numeric identifier of the service. Use `code` in requests, not this. |
| `code` | `string` | obligatorio | Service code — the value that goes into a template’s `service_key` and into the `GET /usage/{service}` path. |
| `name` | `string` | obligatorio | Internal service name. |
| `display_name` | `string` | obligatorio | Service name for display, translated into the account language. |
| `label` | `null \| array<any> \| string \| object` — nullable | — |  |
| `payg_access` | `string` | obligatorio | Whether pay-as-you-go top-up beyond the subscription quota is allowed for this service. |
| `billing_mode` | `BillingMode` — `subscription` · `pay_as_you_go` | obligatorio | How the service is billed: per call, per character, per second or per image. It determines which of the `units_per_*` fields is in effect. |
| `unit_asset_id` | `integer` — nullable | obligatorio | ID of the asset the service units are denominated in. The asset itself is in `unit_asset`. |
| `unit_asset` | `Asset` | — | The service’s unit asset; its `precision` is what converts the integer `units_*` values into decimals. |
| `unit_asset.id` | `integer` | obligatorio | Internal identifier of the asset. |
| `unit_asset.code` | `string` | obligatorio | Asset code: `LUMC` is the internal currency, `TOKEN` the generation tokens. |
| `unit_asset.kind` | `AssetKind` — `money` · `unit` | obligatorio | Kind of asset: money or consumable units. It decides whether an amount counts as a payment or as quota consumption. |
| `unit_asset.precision` | `integer` | obligatorio | Number of decimal places. **The load-bearing field:** every integer amount in this asset is divided by `10^precision` to obtain the real value. Do not assume the divisor is 100. |
| `unit_asset.name` | `string` | obligatorio | Display name of the asset, in the account language. |
| `unit_asset.deleted_at` | `string` — date-time — nullable | obligatorio | When the asset was retired, ISO 8601. `null` while it is in use. |
| `unit_asset.created_at` | `string` — date-time — nullable | obligatorio | When the asset was created, ISO 8601. |
| `unit_asset.updated_at` | `string` — date-time — nullable | obligatorio | When the asset last changed, ISO 8601. |
| `required_entitlement_id` | `integer` — nullable | obligatorio | ID of the entitlement required to use the service. `null` means the service is open to everyone. |
| `required_entitlement` | `Entitlement` | — | The subscription entitlement that unlocks the service. Whether you have it is visible in `GET /usage`. |
| `required_entitlement.id` | `integer` | obligatorio | Internal identifier of the entitlement. |
| `required_entitlement.code` | `string` | obligatorio | Entitlement code — a service checks it to decide whether you have access. |
| `required_entitlement.name` | `string` | obligatorio | Display name of the entitlement, in the account language. |
| `required_entitlement.metadata` | `object` — nullable | obligatorio | Extra attributes of the entitlement. The key set is free-form. |
| `required_entitlement.is_active` | `boolean` | obligatorio | Whether the entitlement is active. |
| `required_entitlement.created_at` | `string` — date-time — nullable | obligatorio | When the entitlement was created, ISO 8601. |
| `required_entitlement.updated_at` | `string` — date-time — nullable | obligatorio | When the entitlement last changed, ISO 8601. |
| `required_entitlement.is_unlimited` | `boolean` | — | Whether this capability is unlimited under the plan. Present only when the entitlement is returned in a plan context. |
| `units_per_call` | `integer` — nullable | obligatorio | A value in the asset's minor units: the real one is `value / 10^precision`, with `precision` carried by `unit_asset`. |
| `units_per_char` | `integer` — nullable | obligatorio | How many units one character costs — used under per-character billing. The value is in the asset’s minor units. |
| `units_per_image` | `integer` — nullable | obligatorio | How many units one image costs. The value is in the asset’s minor units. |
| `units_per_second` | `integer` — nullable | obligatorio | How many units one second of output costs. The value is in the asset’s minor units. |
| `min_billable_chars` | `integer` — nullable | obligatorio | The minimum number of characters billed even when the text is shorter. It guards against negligible orders. |
| `lumcoin_per_token` | `integer` — nullable | obligatorio | Price of a single token when topping up from LMC, in minor units. The top-up cost is `tokens × lumcoin_per_token`. |
| `lumc_precision` | `integer` | obligatorio | Number of LMC decimal places — the `10^precision` divisor for every amount given in minor units. |
| `price_lumc_minor` | `integer` — nullable | obligatorio | Price in LMC minor units per `unit_size` natural units of the service. `null` means the service is priced through tokens instead. |
| `unit_size` | `integer` | obligatorio | How many natural service units `price_lumc_minor` is quoted for — for example, per 1000 characters. |
| `uses_money_first_pricing` | `boolean` | obligatorio | `true` means the price is set directly in LMC (`price_lumc_minor`) rather than derived from tokens. It affects how the figure is computed, not what you pay. |
| `rate_unit` | `string` — nullable | obligatorio | Natural billing unit for display: characters, seconds or images. |
| `display_category` | `string` — nullable | obligatorio | Catalogue section the service is filed under in the interface. |
| `is_premium` | `boolean` | obligatorio | Whether the service is flagged as premium. A storefront hint; access itself is governed by `required_entitlement`. |
| `display_order` | `integer` | obligatorio | Sort weight in the catalogue: lower comes first. |
| `metadata` | `object` — nullable | obligatorio | Extra service attributes. The key set is free-form and may change — do not depend on any particular one. |
| `is_active` | `boolean` | obligatorio | Whether the service is listed in the catalogue. Order intake is stopped by maintenance_mode, not by this flag. |
| `maintenance_mode` | `boolean` | obligatorio | The service is under maintenance: creating an order, retrying and regenerating return 503. Orders already accepted keep processing. |
| `access_level` | `string` | — |  |
| `maintenance_auto_resume` | `boolean` | — |  |
| `maintenance_started_at` | `string` | — |  |
| `maintenance_note` | `string` | — |  |
| `created_at` | `string` — date-time — nullable | obligatorio | When the service was created, ISO 8601. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the service settings last changed, ISO 8601. |

**Ejemplo**

```json
{
  "id": 1,
  "code": "string",
  "name": "string",
  "display_name": "string",
  "label": [
    "string"
  ],
  "payg_access": "string",
  "billing_mode": "subscription",
  "unit_asset_id": 1,
  "unit_asset": {
    "id": 1,
    "code": "string",
    "kind": "money",
    "precision": 1,
    "name": "string",
    "deleted_at": "string",
    "created_at": "string",
    "updated_at": "string"
  },
  "required_entitlement_id": 1,
  "required_entitlement": {
    "id": 1,
    "code": "string",
    "name": "string",
    "metadata": {},
    "is_active": true,
    "created_at": "string",
    "updated_at": "string",
    "is_unlimited": true
  },
  "units_per_call": 1,
  "units_per_char": 1,
  "units_per_image": 1,
  "units_per_second": 1,
  "min_billable_chars": 1,
  "lumcoin_per_token": 1,
  "lumc_precision": 1,
  "price_lumc_minor": 1,
  "unit_size": 1,
  "uses_money_first_pricing": true,
  "rate_unit": "string",
  "display_category": "string",
  "is_premium": true,
  "display_order": 1,
  "metadata": {},
  "is_active": true,
  "maintenance_mode": true,
  "access_level": "string",
  "maintenance_auto_resume": true,
  "maintenance_started_at": "string",
  "maintenance_note": "string",
  "created_at": "string",
  "updated_at": "string"
}
```

## StoreOrderRequest

Order creation parameters. Accepted both as `application/json` and as
`multipart/form-data` (the latter when `input_files` are involved).

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `template_id` | `string` — uuid — nullable | — | Template UUID — it determines the service, the task type and every generation setting. **Either `template_id` or `task_type` is required**; if both are sent, the template wins. Templates are the usual way to work: settings are defined once, and the order only carries the text. To deviate from them just once, use `config_override`. |
| `task_type` | `string` — `tts` · `image` · `txt2img` · `remix` · `image_edit` · `voice_clone` · `sfx` · `music` · `voice_search` — nullable | — | Task type for generation **without a template**. Required when `template_id` is not sent. \| Value \| What it does \| Where the parameters go \| \| --- \| --- \| --- \| \| `sfx` \| A sound effect from a text description \| `task_data` \| \| `music` \| A music track from a description \| `task_data` \| \| `voice_search` \| Finding voices similar to your audio clip \| `input_files` (audio) + `task_data.top` \| `tts` requires a template — that is where the voice and model live. |
| `name` | `string` — ≤ 120 caracteres — nullable | — | Human-readable order name: it becomes the name of the downloaded file and of the ZIP archive. If omitted, the server derives one, in this order: the uploaded file's name without its extension → the first ~60 characters of the text on a word boundary (pause tags `{{pause=…}}` are stripped). |
| `task_data` | `object` | — | Generation parameters for a **template-less** order — a one-off "temporary template". A JSON object; multipart clients may send it as a single JSON string. > **Put the keys at the root of the object, with no wrapper.** > `GET /templates/config-options` shows the same parameters grouped into a section > (`sfx_settings`, `music_settings`) — that is the shape of a settings UI, not the > shape of a request. Sending `{"sfx_settings": {"text": "…"}}` returns `422` > "text is required": the wrapper hid the key. **SFX** (`task_type: "sfx"`) — one generation yields exactly one file: \| Key \| Type \| Default \| Purpose \| \| --- \| --- \| --- \| --- \| \| `text` \| string, **required** \| — \| Description of the sound; English prompts work best \| \| `prompt_influence` \| number `0..1` \| `0.3` \| How strictly to follow the prompt \| \| `duration_seconds` \| number `0.5..30` \| `null` \| `null` = automatic length \| \| `loop` \| boolean \| `false` \| Seamless looping \| \| `output_format` \| `mp3_44100_128` \\| `mp3_44100_192` \\| `opus_48000_128` \| `mp3_44100_128` \| Output format \| **Music** (`task_type: "music"`) — `n_variants` generations yield that many files: \| Key \| Type \| Default \| Purpose \| \| --- \| --- \| --- \| --- \| \| `prompt` \| string, **required** \| — \| Description of the track: genre, mood, instruments \| \| `n_variants` \| integer `1..4` \| `1` \| How many variants to generate. **Multiplies the price** and yields the same number of files in `result.files[]` \| \| `lyrics_text` \| string \| `null` \| Song lyrics; if empty and `force_instrumental` is off, the model may add vocals on its own \| \| `force_instrumental` \| boolean \| `false` \| Instrumental only, no vocals \| \| `music_length_ms` \| integer `10000..30000` \| `30000` \| Track length in **milliseconds**: 10–**30 s at most**, above `30000` → 422 \| \| `model_id` \| `music_v2` \| `music_v2` \| Currently the only value \| **Voice Search** (`task_type: "voice_search"`) — the audio clip travels in `input_files`; only one parameter lives here: \| Key \| Type \| Default \| Purpose \| \| --- \| --- \| --- \| --- \| \| `top` \| integer `1..50` \| `10` \| How many similar voices to return \| ### What drives the price What counts is the **number of generations**, not their size: \| Type \| Price \| Does NOT affect the price \| \| --- \| --- \| --- \| \| `sfx` \| One service rate per order \| `duration_seconds`, the length of `text` \| \| `music` \| Rate × `n_variants` \| `music_length_ms`, the length of `prompt`, `lyrics_text` \| \| `voice_search` \| One rate per order \| Clip duration, `top` \| A five-minute track costs exactly what a ten-second one costs — you pay per call to the model. What was actually charged comes back in the order's `price_units`. The server merges the service's `default_config` underneath your values (yours win) — switch that off with `skip_service_defaults`. A value outside its range or enum returns `422` **before** billing: no order is created and no funds are reserved. |
| `config_override` | `object` | — | A one-off deviation from the template's settings — the **only way to change parameters for a single order without creating a new template**. The shape is the same JSON object as the template's `config`, applied on top of it for this order only. For example, to narrate one order with a different voice: `{"tts_settings": {"voice_id": "<OTHER_VOICE_ID>"}}` — the rest of the template survives. Paths absent from the service schema are **silently dropped** (a typo in a key looks like "the setting did not apply"); the remaining values are validated against the schema — out of range or enum returns `422`. Works only together with `template_id`: template-less `sfx`/`music` already keep everything in `task_data`. > **Send only the keys you are changing.** An explicit `null` does not mean "keep the > template value" — it means "erase it": it overwrites the template's value with an > empty one for this order. A client that serialises its whole settings form and puts > `null` into the untouched fields will silently reset half the template that way. An > absent key is the only way to say "leave this alone". ### Paragraph narration mode By default the text is cut into fragments back to back, by technical size, and paragraph boundaries play no part. Paragraph mode changes the order of operations: the text is first split on **blank lines** into paragraphs, and each paragraph is then cut within itself. The key sits next to `tts_settings`, not inside it — at the root of `config_override`: ```json {"generation_mode": "paragraph"} ``` \| Value \| What it does \| \| --- \| --- \| \| `paragraph` \| A paragraph becomes a unit of generation in its own right \| \| `default` \| Continuous cutting by fragment size (same as omitting the key) \| Supported by `elevenlabs` and `heygen`; other services ignore the key — there is no rejection, the mode simply does not engage. **What changes in the response:** the order gains `paragraphs[]` (per paragraph: its index, fragment count, aggregate status and progress), and fragments gain `paragraph_index`. > **This affects the price.** The minimum billable volume applies to EVERY paragraph > separately rather than to the order as a whole: five short paragraphs cost five > minimums, whereas the same text in the default mode would cost one. **It affects speed too.** A paragraph is a task of its own, and no more than 10 single-fragment paragraphs plus 5 multi-fragment ones run at a time per order; the rest wait for a slot. A text of a hundred short paragraphs therefore proceeds in waves — but the first results arrive sooner than with continuous cutting. A template's `config` accepts the same key, which makes the mode permanent for every order built from that template. `GET /templates/config-options` does not list it: that directory describes the service's settings, while the mode is chosen per order. |
| `skip_service_defaults` | `boolean` — nullable | — | Do not merge the service's `default_config` into `task_data`. Send `true` when you already have the complete parameter set and the worker should receive exactly that — the server will not add a single default key. The flag is stored on the order: `POST /orders/{order}/retry` reproduces the same behaviour. It has no effect on template-based orders — those take their config from `template.config` plus `config_override`, not from the service defaults. |
| `input_text` | `string` — nullable | — | The task text. For `tts` this is what gets narrated; the server splits it into chunks by itself. **There are three channels for text and they are equal** — every check (pause limits, "nothing to narrate") applies to each of them: \| Channel \| When to use it \| \| --- \| --- \| \| `input_text` \| The usual way: the text right in the request \| \| A `.txt` in `input_files[]` \| Long text as a file; its contents become the task text \| \| `task_data.text` \| Template-less orders only \| What happens to the text before it is cut, and how markup inside it affects the price, is covered in the “Markup inside the text” and “How the text is cut” sections of this method's description. For template-less `sfx`/`music` this field is **unused** — put the description into `task_data.text` (SFX) or `task_data.prompt` (Music). |
| `confirm_payg_topup` | `boolean` — nullable | — | Consent to top up from the LMC balance when the subscription quota does not cover the whole order. **Normally not needed:** the top-up is charged automatically, and the field is ignored. It only matters in the fallback mode with explicit confirmation, which the platform operator may enable — the rules below describe that mode. **The spending order never changes: subscription quota first, LMC only for the remainder.** If the quota covers the order, this flag changes nothing and the balance is not touched at all. **The flag alone charges nothing.** Consent is only valid together with a fresh `quote_token` from a `402` response, bound to you, the service and the exact task volume. Sent without a token (or with an expired or foreign one), `confirm_payg_topup: true` simply returns `402` again — nothing is charged. The working cycle: send the order → `402` with `shortfall_tokens`, `shortfall_lmc`, `quote_token`, `expires_at` → show the amount to your user → repeat **the same** request with `confirm_payg_topup: true` and that `quote_token`. The token lives about 60 seconds. Consent is an upper bound: if the top-up turns out cheaper at charge time, the actual amount is taken; if it got more expensive (a concurrent order ate the quota), you get `409 quote_mismatch` — request a new `402`. |
| `quote_token` | `string` — nullable | — | The signed top-up quote from a `402` response — pass the string as-is, together with `confirm_payg_topup: true`. The token is bound to the user, the service and the task volume, and lives about 60 seconds. An expired, altered or foreign token does not apply: the request returns `402` with a new quote. |
| `input_files` | `array<file>` — nullable | — | Input files — `multipart/form-data` only, up to 20 MB per file. A single file may be sent in the `input_file` field instead. \| Task type \| File \| \| --- \| --- \| \| `tts` (narration) \| A `.txt` — **a full replacement for `input_text`**: its contents become the text to narrate \| \| `voice_search` \| An audio clip, **required**. The type is checked by content rather than extension; a foreign format (image, archive) gives `422` before any charge. Longer than 60 seconds is truncated, and the response says so \| \| `sfx`, `music` \| Unused — the whole description lives in `task_data` \| |

**Ejemplo**

```json
{
  "template_id": "4d3e9f8b-2c1a-4f5a-8b9c-0d1e2f3a4b5c",
  "task_type": "sfx",
  "name": "Приветствие для лендинга",
  "task_data": {
    "text": "Тяжёлая деревянная дверь скрипит и захлопывается",
    "duration_seconds": 4
  },
  "config_override": {
    "tts_settings": {
      "voice_id": "EXAVITQu4vr4xnSDxMaL"
    }
  },
  "skip_service_defaults": false,
  "input_text": "Здравствуйте! Рады видеть вас в Lumean.",
  "confirm_payg_topup": false,
  "quote_token": "string",
  "input_files": [
    "<binary>"
  ]
}
```

## StoreTemplateRequest

A new generation template. `config` is validated against the service schema — take the
structure for your `service_key` from `GET /templates/config-options`.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `folder_id` | `string` — uuid — nullable | — | UUID of one of your folders. Omitted — the template is created at the root. |
| `service_key` | `string` | obligatorio | Code of the service the template is built for: a short latin string — `elevenlabs`, `heygen`, `lumimg`, `sfx`, `music`. The codes available to you are listed by `GET /usage` in its `service_code` field; this choice determines what `config` will accept. |
| `name` | `string` — ≤ 255 caracteres | obligatorio | Template name, up to 255 characters. Shown in `GET /templates` and in the web interface. |
| `is_public` | `boolean` | — | Publish the template in the shared catalogue. Defaults to `false` — visible only to you. |
| `config` | `object` | obligatorio | Generation settings. The structure depends on `service_key`; the accepted keys, ranges and value lists come from `GET /templates/config-options?service=<code>` — take them from there instead of guessing. A minimal valid `config` for `elevenlabs`: `{"tts_settings": {"mode": "mode_v1", "model_id": "eleven_multilingual_v2", "voice_id": "<VOICE_ID>", "advanced_voice_settings": true, "voice_settings": {"stability": 0.5, "similarity_boost": 0.75, "use_speaker_boost": true, "speed": 1.0}}}` ### Fine voice settings need a flag Which `voice_settings` reach the speech engine depends on the model and on the `tts_settings.advanced_voice_settings` flag (defaults to `false`): \| Model \| Without the flag \| With the flag \| \| --- \| --- \| --- \| \| `eleven_v3`, `eleven_v3_beta` \| `stability` \| all five \| \| `eleven_v4`, `eleven_v4_exp` \| `stability`, `similarity_boost` \| all five \| \| others \| all five \| all five \| Values that do not reach the engine are stored on the template and pass validation, but do not affect the audio. There is no error: it just looks like "the setting does not work" — most often with `speed` on v3/v4. `voice_settings.stability` carries a dependency of the same kind: on models of the `eleven_v3` family its step is 0.5, so only `0`, `0.5` and `1` are accepted. ### Stitching prosody across chunks Long text is split into chunks, and each one is synthesised by its own request — which is why the pitch can jump at the joins. Two optional boolean flags ask the engine to take the neighbours into account: `tts_settings.prev_next_text` sends the neighbouring chunk text, `tts_settings.request_ids` sends the ids of the neighbouring generations. Both default to `false`. They only affect how the joins sound; pricing and chunking are unchanged. **Only ONE of them may be enabled.** Sending both is a `422`: given both the text and the ids, the engine uses the ids only and ignores the text, so "both on" would be a silently disabled `prev_next_text`. ### Text normalization `tts_settings.apply_text_normalization` has three modes: `auto` (the engine decides on its own whether to normalize, for example spelling out numbers), `on` (always normalize), `off` (skip it). Defaults to `auto`. |

**Ejemplo**

```json
{
  "folder_id": "string",
  "service_key": "elevenlabs",
  "name": "Диктор — женский, спокойный",
  "is_public": false,
  "config": {}
}
```

## TemplateList

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `items` | `array<Template>` | obligatorio | Records on the current page, in the list’s sort order. |
| `items[].id` | `string` | obligatorio | Template UUID. Put it into `template_id` when creating an order. |
| `items[].user_id` | `integer` | obligatorio | ID of the template owner. |
| `items[].slug` | `string` | obligatorio | Short public identifier used for sharing. `null` on a template that was never shared. |
| `items[].name` | `string` | obligatorio | Template name — for humans only; it does not affect generation. |
| `items[].service_key` | `string` | obligatorio | Code of the service whose schema validates `config`: `elevenlabs`, `lumimg`, and so on. |
| `items[].service` | `Service \| null` — nullable | obligatorio | The template’s service for reference: name and pricing, without configuration schemas. `null` means no service with that code exists any more. |
| `items[].config` | `object` | obligatorio | Generation settings: voice, model, speed and so on — the set of keys is defined by the service. Look up allowed values in `GET /templates/config-options?service=<code>`; anything outside the schema is rejected with `422`. Inside an order (`template` in `GET /orders/{order}`) this is the order’s own settings — the snapshot taken at creation with `config_override` applied, not the template’s current configuration (for orders created before late September 2026 — the current template configuration with `config_override`). |
| `items[].is_public` | `boolean` | obligatorio | Whether the template is published in the shared catalogue. |
| `items[].folder_id` | `string` | obligatorio | UUID of the folder holding the template, or `null` for the root. The folder tree is visible in `GET /templates/browse`. |
| `items[].created_at` | `string` — date-time — nullable | obligatorio | When the template was created, ISO 8601. |
| `items[].updated_at` | `string` — date-time — nullable | obligatorio | When the template last changed, ISO 8601. |
| `current_page` | `integer` | obligatorio | Current page number, starting from one. |
| `last_page` | `integer` | obligatorio | Number of the last page. The walk is over once `current_page` equals `last_page`. |
| `per_page` | `integer` | obligatorio | Page size the server applied. |
| `total` | `integer` | obligatorio | Total number of records matching the filter. |

**Ejemplo**

```json
{
  "items": [
    {
      "id": "string",
      "user_id": 1,
      "slug": "string",
      "name": "string",
      "service_key": "string",
      "service": {
        "id": 1,
        "code": "string",
        "name": "string",
        "display_name": "string",
        "label": [
          null
        ],
        "payg_access": "string",
        "billing_mode": "subscription",
        "unit_asset_id": 1,
        "unit_asset": {
          "id": 1,
          "code": "string",
          "kind": "money",
          "precision": 1,
          "name": "string",
          "deleted_at": "string",
          "created_at": "string",
          "updated_at": "string"
        },
        "required_entitlement_id": 1,
        "required_entitlement": {
          "id": 1,
          "code": "string",
          "name": "string",
          "metadata": {},
          "is_active": true,
          "created_at": "string",
          "updated_at": "string",
          "is_unlimited": true
        },
        "units_per_call": 1,
        "units_per_char": 1,
        "units_per_image": 1,
        "units_per_second": 1,
        "min_billable_chars": 1,
        "lumcoin_per_token": 1,
        "lumc_precision": 1,
        "price_lumc_minor": 1,
        "unit_size": 1,
        "uses_money_first_pricing": true,
        "rate_unit": "string",
        "display_category": "string",
        "is_premium": true,
        "display_order": 1,
        "metadata": {},
        "is_active": true,
        "maintenance_mode": true,
        "access_level": "string",
        "maintenance_auto_resume": true,
        "maintenance_started_at": "string",
        "maintenance_note": "string",
        "created_at": "string",
        "updated_at": "string"
      },
      "config": {},
      "is_public": true,
      "folder_id": "string",
      "created_at": "string",
      "updated_at": "string"
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 1,
  "total": 1
}
```

## TemplateItem

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `type` | `string` — `template` | obligatorio |  |
| `id` | `string` | obligatorio |  |
| `name` | `string` | obligatorio |  |
| `slug` | `string` | — |  |
| `service_key` | `string` | — |  |
| `service` | `Service \| null` — nullable | — |  |
| `config` | `object \| string` | — |  |
| `is_public` | `string` | — |  |
| `folder_id` | `string` | — |  |
| `created_at` | `string` | obligatorio |  |
| `updated_at` | `string` | obligatorio |  |
| `templates_count` | `string \| integer` | — |  |

**Ejemplo**

```json
{
  "type": "template",
  "id": "string",
  "name": "string",
  "slug": "string",
  "service_key": "string",
  "service": {
    "id": 1,
    "code": "string",
    "name": "string",
    "display_name": "string",
    "label": [
      "string"
    ],
    "payg_access": "string",
    "billing_mode": "subscription",
    "unit_asset_id": 1,
    "unit_asset": {
      "id": 1,
      "code": "string",
      "kind": "money",
      "precision": 1,
      "name": "string",
      "deleted_at": "string",
      "created_at": "string",
      "updated_at": "string"
    },
    "required_entitlement_id": 1,
    "required_entitlement": {
      "id": 1,
      "code": "string",
      "name": "string",
      "metadata": {},
      "is_active": true,
      "created_at": "string",
      "updated_at": "string",
      "is_unlimited": true
    },
    "units_per_call": 1,
    "units_per_char": 1,
    "units_per_image": 1,
    "units_per_second": 1,
    "min_billable_chars": 1,
    "lumcoin_per_token": 1,
    "lumc_precision": 1,
    "price_lumc_minor": 1,
    "unit_size": 1,
    "uses_money_first_pricing": true,
    "rate_unit": "string",
    "display_category": "string",
    "is_premium": true,
    "display_order": 1,
    "metadata": {},
    "is_active": true,
    "maintenance_mode": true,
    "access_level": "string",
    "maintenance_auto_resume": true,
    "maintenance_started_at": "string",
    "maintenance_note": "string",
    "created_at": "string",
    "updated_at": "string"
  },
  "config": {},
  "is_public": "string",
  "folder_id": "string",
  "created_at": "string",
  "updated_at": "string"
}
```

## Template

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `string` | obligatorio | Template UUID. Put it into `template_id` when creating an order. |
| `user_id` | `integer` | obligatorio | ID of the template owner. |
| `slug` | `string` | obligatorio | Short public identifier used for sharing. `null` on a template that was never shared. |
| `name` | `string` | obligatorio | Template name — for humans only; it does not affect generation. |
| `service_key` | `string` | obligatorio | Code of the service whose schema validates `config`: `elevenlabs`, `lumimg`, and so on. |
| `service` | `Service \| null` — nullable | obligatorio | The template’s service for reference: name and pricing, without configuration schemas. `null` means no service with that code exists any more. |
| `config` | `object` | obligatorio | Generation settings: voice, model, speed and so on — the set of keys is defined by the service. Look up allowed values in `GET /templates/config-options?service=<code>`; anything outside the schema is rejected with `422`. Inside an order (`template` in `GET /orders/{order}`) this is the order’s own settings — the snapshot taken at creation with `config_override` applied, not the template’s current configuration (for orders created before late September 2026 — the current template configuration with `config_override`). |
| `is_public` | `boolean` | obligatorio | Whether the template is published in the shared catalogue. |
| `folder_id` | `string` | obligatorio | UUID of the folder holding the template, or `null` for the root. The folder tree is visible in `GET /templates/browse`. |
| `created_at` | `string` — date-time — nullable | obligatorio | When the template was created, ISO 8601. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the template last changed, ISO 8601. |

**Ejemplo**

```json
{
  "id": "string",
  "user_id": 1,
  "slug": "string",
  "name": "string",
  "service_key": "string",
  "service": {
    "id": 1,
    "code": "string",
    "name": "string",
    "display_name": "string",
    "label": [
      "string"
    ],
    "payg_access": "string",
    "billing_mode": "subscription",
    "unit_asset_id": 1,
    "unit_asset": {
      "id": 1,
      "code": "string",
      "kind": "money",
      "precision": 1,
      "name": "string",
      "deleted_at": "string",
      "created_at": "string",
      "updated_at": "string"
    },
    "required_entitlement_id": 1,
    "required_entitlement": {
      "id": 1,
      "code": "string",
      "name": "string",
      "metadata": {},
      "is_active": true,
      "created_at": "string",
      "updated_at": "string",
      "is_unlimited": true
    },
    "units_per_call": 1,
    "units_per_char": 1,
    "units_per_image": 1,
    "units_per_second": 1,
    "min_billable_chars": 1,
    "lumcoin_per_token": 1,
    "lumc_precision": 1,
    "price_lumc_minor": 1,
    "unit_size": 1,
    "uses_money_first_pricing": true,
    "rate_unit": "string",
    "display_category": "string",
    "is_premium": true,
    "display_order": 1,
    "metadata": {},
    "is_active": true,
    "maintenance_mode": true,
    "access_level": "string",
    "maintenance_auto_resume": true,
    "maintenance_started_at": "string",
    "maintenance_note": "string",
    "created_at": "string",
    "updated_at": "string"
  },
  "config": {},
  "is_public": true,
  "folder_id": "string",
  "created_at": "string",
  "updated_at": "string"
}
```

## UpdateTemplateRequest

Partial template update: send only the fields you are changing. `service_key` and
`config` change **together** — the config is validated against the new service's schema.

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `folder_id` | `string` — uuid — nullable | — | UUID of the folder to move the template into. `null` moves it to the root. |
| `service_key` | `string` | — | New service code. Changes only together with `config` — the config is validated against the new service's schema. |
| `name` | `string` — ≤ 255 caracteres | — | New template name, up to 255 characters. |
| `is_public` | `boolean` | — | Publish the template in the shared catalogue, or unpublish it. |
| `config` | `object` | — | The complete new generation settings (not a partial patch). The accepted structure comes from `GET /templates/config-options?service=<code>`. |

**Ejemplo**

```json
{
  "folder_id": "string",
  "service_key": "elevenlabs",
  "name": "string",
  "is_public": true,
  "config": {}
}
```

## UserLibraryList

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `items` | `array<object>` | obligatorio | Records on the current page, in the list’s sort order. |
| `current_page` | `integer` | obligatorio | Current page number, starting from one. |
| `last_page` | `integer` | obligatorio | Number of the last page. The walk is over once `current_page` equals `last_page`. |
| `per_page` | `integer` | obligatorio | Page size the server applied. |
| `total` | `integer` | obligatorio | Total number of records matching the filter. |

**Ejemplo**

```json
{
  "items": [
    {}
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 1,
  "total": 1
}
```

## VoiceLanguage

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `integer` | obligatorio | Internal identifier of the voice’s language version. |
| `language_code` | `string` | obligatorio | Language code, ISO-639-1. It is also the key used in `preview_urls`. |
| `status` | `string` | obligatorio | Cloning state for this language. Orders are accepted only in a language whose clone is ready. |
| `reference_duration_ms` | `integer` — nullable | obligatorio | Duration of the reference recording in milliseconds — the clone was trained on it. |
| `model_version` | `integer` | obligatorio | Version of the trained model. It increments whenever the voice is retrained. |
| `failure_reason` | `string` — nullable | obligatorio | Why cloning failed. `null` when there was no failure. |
| `clone_started_at` | `string` — date-time — nullable | obligatorio | When cloning started, ISO 8601. |
| `clone_completed_at` | `string` — date-time — nullable | obligatorio | When cloning finished, ISO 8601. `null` means it is still running or it failed. |
| `updated_at` | `string` — date-time — nullable | obligatorio | When the language version last changed, ISO 8601. |

**Ejemplo**

```json
{
  "id": 1,
  "language_code": "string",
  "status": "string",
  "reference_duration_ms": 1,
  "model_version": 1,
  "failure_reason": "string",
  "clone_started_at": "string",
  "clone_completed_at": "string",
  "updated_at": "string"
}
```

## VoiceTag

`object`

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `id` | `integer` | obligatorio | Internal identifier of the tag. |
| `code` | `string` | obligatorio | Tag code — the stable value to filter by, unlike the translatable `name`. |
| `name` | `string` | obligatorio | Tag name in the account language. |
| `description` | `string` — nullable | obligatorio | Explanation of the tag in the account language, when the author provided one. |
| `color` | `string` | obligatorio | Tag colour in HEX — a styling hint. |
| `sort_order` | `integer` | obligatorio | Sort weight within the tag list: lower comes first. |

**Ejemplo**

```json
{
  "id": 1,
  "code": "string",
  "name": "string",
  "description": "string",
  "color": "string",
  "sort_order": 1
}
```

## AssetKind

`string`: `money` · `unit`

**Ejemplo**

```json
"money"
```

## BillingMode

`string`: `subscription` · `pay_as_you_go`

**Ejemplo**

```json
"subscription"
```

## TaskType

`string`: `tts` · `image` · `txt2img` · `remix` · `image_edit` · `voice_clone` · `sfx` · `music` · `voice_search`

**Ejemplo**

```json
"tts"
```

---

- Esta página en el navegador: https://lumean.app/es/developers/docs/objects
- Referencia completa legible por máquina: https://api.lumean.app/docs/llm.md
