---
title: "POST /orders/{order}/items/{item}/retry — Retry Order Item"
url: https://lumean.app/es/developers/docs/api/post-orders-order-items-item-retry
locale: es
description: "Retry Order Item"
generated: 2026-10-17
operationId: orderItem.retry
method: POST
path: "/orders/{order}/items/{item}/retry"
scopes: [orders.write]
spec_version: 0.0.1
---

# POST /orders/{order}/items/{item}/retry

**Retry Order Item**

Retries one failed chunk. This is how a `partially_completed` order is brought to
`completed` — walk over every `policy_flagged`/`failed` chunk.

**Billing:** within the already paid length (`free_length`) the retry is paid for
out of the funds already locked by the chunk — no new charge and no key token quota.
A text LONGER than paid is charged for the excess (quota first, counted in the key's
token quota — the delta only) and refunded if the retry fails. The limits come from
`GET /orders/{order}/items/{item}/text`.

Two kinds of failure, handled differently:
- `failed` — a technical error (worker timeout, generation glitch). Retrying the same
  text is usually enough: send an empty body.
- `policy_flagged` — the provider rejected the content. **The same text will be
  rejected again** — fetch it via `GET /orders/{order}/items/{item}/text`, rephrase,
  and send it back in `text`.

Without `text` the previous text is retried; if it was already deleted with the order's
storage retention, you get `422` with `reason: input_expired` (a retry with a new
`text` goes through).

Not available for `sfx`/`music`: those are single-shot generations. Limit — 5 attempts
per chunk.

**Required key permission:** `orders.write`.

- Permiso requerido: `orders.write`

## Petición

```bash
curl -X POST 'https://api.lumean.app/api/public/orders/{order}/items/{item}/retry' \
  -H 'Accept: application/json' \
  -H 'X-API-KEY: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
```

## Parámetros

| Campo | En | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- | --- |
| `order` | path | `string` | obligatorio | Order UUID — 36 characters shaped like `9f8b2c1a-4d3e-4f5a-8b9c-0d1e2f3a4b5c`, not a number. Take it from the `id` field: `POST /orders` returns it on creation and `GET /orders` lists it. Someone else’s order will not open with your key — you get a `404`. default: `9f8b2c1a-4d3e-4f5a-8b9c-0d1e2f3a4b5c` |
| `item` | path | `string` | obligatorio | Order chunk UUID — 36 characters; neither a number nor a position. Take it from an item’s `id` field: `GET /orders/{order}/items` returns the list, and the same set sits in `items[]` of the detailed order response. The chunk’s position is the neighbouring `chunk_index` field, which does **not** go into the path. default: `2b7d1e60-5a44-4a1e-9f3c-7c0d9e8a1b23` |

## Cuerpo de la petición

The body is optional: without it the fragment is retried with its previous text. The
`text` field is what you need after a content-policy rejection (`policy_flagged`) —
the same text would be rejected again.

Within the paid length (`free_length` from `GET …/items/{item}/text`) a retry is free —
it inherits the original fragment’s price. A text longer than paid (up to
`max_billable_length`) is charged for the excess; not enough money — `402`.

Content-Type: `application/json`

| 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
{}
```

## Escenarios del cuerpo

### Retry as-is

For a chunk in status failed (technical error) — retrying the previous text is usually enough.

```json
{}
```

### With corrected text

For policy_flagged: retrying the same text will be rejected again — send a rephrased version.

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

## Respuestas

### 201 — The chunk was queued for retry. The order stays `partially_completed` until every chunk settles.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `success` | `boolean` | obligatorio | Success flag. Branch on the HTTP status code instead: any 2xx response carries `true` here, while an error comes back in a different shape that need not contain this field at all. |
| `message` | `string` | obligatorio | A human-readable note in the account language. Fine to show to a user; do not parse it — the wording changes without notice and is not an error code. |
| `data` | `OrderItem` | obligatorio | A new retry record with its own `id`; `parent_item_id` points at the original fragment. A retry is free — it costs no new tokens. |
| `data.id` | `string` | obligatorio | Chunk UUID. Use it in `/orders/{order}/items/{item}/…` paths. |
| `data.order_id` | `string` | obligatorio | UUID of the order this chunk belongs to. |
| `data.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. |
| `data.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. |
| `data.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`. |
| `data.parent_item_id` | `string` | obligatorio | UUID of the source chunk — present on `retry` and `regeneration` records. `null` on an original chunk. |
| `data.original_text_length` | `integer` | obligatorio | Length of the text the fragment was created with. It is the ceiling for `text` in `regenerate`. |
| `data.current_text_length` | `integer` | obligatorio | Length of the fragment’s current text: after a regeneration it differs from `original_text_length`. |
| `data.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). |
| `data.consumed_units` | `integer` | obligatorio | How many tokens were actually charged for this fragment. Zero while the fragment is unfinished. |
| `data.remaining_locked` | `integer` | obligatorio | How many tokens are still reserved for the fragment. Drops to zero once the fragment finishes or is cancelled. |
| `data.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. |
| `data.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. |
| `data.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. |
| `data.attempt_number` | `integer` | obligatorio | Attempt number for this fragment, starting at 1. It grows with every retry. |
| `data.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. |
| `data.can_regenerate` | `boolean` | obligatorio | Whether a paid regeneration is allowed right now. Available for finished fragments only. |
| `data.created_at` | `string` — date-time — nullable | obligatorio | When the fragment was created, ISO 8601. |
| `data.updated_at` | `string` — date-time — nullable | obligatorio | When the fragment last changed, ISO 8601. |
| `data.failure_reason` | `string` — nullable | — | Machine-readable failure reason — present only on `failed` and `policy_flagged`. Everything else gets `null`. |

**Ejemplo**

```json
{
  "success": true,
  "message": "Order item retry created successfully.",
  "data": {
    "id": "a9b0c1d2-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
    "order_id": "e7f8a9b0-1c2d-4e3f-8a4b-5c6d7e8f9a0b",
    "item_type": "retry",
    "chunk_index": 2,
    "parent_item_id": "f8a9b0c1-2d3e-4f4a-8b5c-6d7e8f9a0b1c",
    "original_text_length": 96,
    "current_text_length": 96,
    "price_units": 96,
    "consumed_units": 0,
    "remaining_locked": 96,
    "status": "pending",
    "result_file": null,
    "attempt_number": 2,
    "can_retry": false,
    "can_regenerate": false,
    "created_at": "2026-07-17T13:40:00+00:00",
    "updated_at": "2026-07-17T13:40:00+00:00"
  }
}
```

### 400 — Any other refusal without a machine code (rare): the reason is only in `message`. Refusals with a `reason` come as 402/409/422/503.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `success` | `boolean` | obligatorio | Always `false` in error responses. |
| `message` | `string` | obligatorio | The reason for the rejection in words, in the account language. Meant for display; do not branch on it, the wording changes. |
| `errors` | `null` — nullable | obligatorio | A per-field breakdown — present only on validation errors (`422`): the key names a request field, the value lists the complaints about it. Other codes send `null`, since there is nothing to break down and the whole reason is in `message`. |

**Ejemplo**

```json
{
  "success": false,
  "message": "The operation could not be completed."
}
```

### 401 — The key is missing, unknown, disabled or expired.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `success` | `boolean` | obligatorio | Always `false` in error responses. |
| `message` | `string` | obligatorio | Error text in the key's language (set through the `X-Locale` header). |
| `data` | `null` — nullable | obligatorio | Always `null` when the request is rejected before processing. |

**Ejemplo**

```json
{
  "success": false,
  "message": "API key is missing. Provide it in the X-API-KEY header.",
  "data": null
}
```

### 402 — Not enough money: `reason: insufficient_funds` — the chunk has no locked funds left; `insufficient_balance`/`insufficient_allowance` — nothing to pay the surcharge for a text longer than paid.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `success` | `boolean` | obligatorio | Always `false` in error responses. |
| `message` | `string` | obligatorio | The reason for the rejection in words, in the account language. Meant for display; do not branch on it, the wording changes. |
| `reason` | `string` | obligatorio | Machine-readable reason of a business refusal (for example, `input_expired`, `insufficient_balance`). Branch on it, not on the `message` text. |
| `error_code` | `string` | obligatorio | The same machine-readable code as in `reason` — a second name for the field. The values always match. |

**Ejemplo**

```json
{
  "success": false,
  "message": "Insufficient balance.",
  "reason": "insufficient_balance",
  "error_code": "insufficient_balance"
}
```

### 403 — The key lacks the required permission, or the object belongs to another user.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `message` | `string` | obligatorio | Error overview. |

**Ejemplo**

```json
{
  "success": false,
  "message": "This API key does not have permission to perform this action."
}
```

### 404 — Not found, or not reachable with this key.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `message` | `string` | obligatorio | Error overview. |

**Ejemplo**

```json
{
  "success": false,
  "message": "Resource not found."
}
```

### 409 — A retry of this chunk is already running (`reason: active_retry_exists`) or the order is being stitched (`reason: stitch_in_progress`). Try again later.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `success` | `boolean` | obligatorio | Always `false` in error responses. |
| `message` | `string` | obligatorio | The reason for the rejection in words, in the account language. Meant for display; do not branch on it, the wording changes. |
| `reason` | `string` | obligatorio | Machine-readable reason of a business refusal (for example, `input_expired`, `insufficient_balance`). Branch on it, not on the `message` text. |
| `error_code` | `string` | obligatorio | The same machine-readable code as in `reason` — a second name for the field. The values always match. |

**Ejemplo**

```json
{
  "success": false,
  "message": "A retry for this item is already in progress.",
  "reason": "active_retry_exists",
  "error_code": "active_retry_exists"
}
```

### 422 — Retry is not possible (`reason`): `invalid_order_status` — the order is not `partially_completed`; `invalid_status` — the chunk is not `failed`/`policy_flagged`; `max_attempts_reached` — the attempt limit (5) is exhausted; `generative_not_supported` — `sfx`/`music`; `text_over_capacity`, `content_blocked`, `input_expired` — see the description; `retry_config_outdated` — the order's settings (the template snapshot plus `config_override`) no longer pass the service's current schema, so the chunk cannot be retried as it was — create a new order. Or a body validation error (`errors`).

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `message` | `string` | obligatorio | Errors overview. |
| `errors` | `object` | obligatorio | A detailed description of each field that failed validation. |
| `errors.*` | `array<string>` — claves arbitrarias | — |  |

**Ejemplo**

```json
{
  "message": "string",
  "errors": {
    "key": [
      "string"
    ]
  }
}
```

### 429 — Limit exceeded: either the key's request rate or its token quota. Retry no earlier than `Retry-After`.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `success` | `boolean` | obligatorio | Always `false` in error responses. |
| `message` | `string` | obligatorio | Error text in the key's language (set through the `X-Locale` header). |
| `reason` | `string` | obligatorio | Machine-readable failure reason — branch on this, not on the message text. |
| `error_code` | `string` | obligatorio | The same machine-readable code as in `reason` — a second name for the field. The values always match; branch on either. |
| `retry_after` | `integer` — nullable | — | How many seconds to wait before retrying (the same value is in the `Retry-After` header). |

**Ejemplo**

```json
{
  "success": false,
  "message": "Too many attempts. Please wait a moment and try again.",
  "reason": "rate_limit_exceeded",
  "error_code": "rate_limit_exceeded",
  "retry_after": 30
}
```

### 503 — Work intake for the service is temporarily paused (`reason: service_maintenance`). Try again later.

**Campos de la respuesta**

| Campo | Tipo | Oblig. | Descripción |
| --- | --- | --- | --- |
| `success` | `boolean` | obligatorio | Always `false` in error responses. |
| `message` | `string` | obligatorio | The reason for the rejection in words, in the account language. Meant for display; do not branch on it, the wording changes. |
| `reason` | `string` | obligatorio | Machine-readable reason of a business refusal (for example, `input_expired`, `insufficient_balance`). Branch on it, not on the `message` text. |
| `error_code` | `string` | obligatorio | The same machine-readable code as in `reason` — a second name for the field. The values always match. |

**Ejemplo**

```json
{
  "success": false,
  "message": "The service is temporarily unavailable due to maintenance. Please try again later.",
  "reason": "service_maintenance",
  "error_code": "service_maintenance"
}
```

---

- Esta página en el navegador: https://lumean.app/es/developers/docs/api/post-orders-order-items-item-retry
- Referencia completa legible por máquina: https://api.lumean.app/docs/llm.md
