---
title: "Файлы, ссылки и хранение"
url: https://lumean.app/developers/docs/guide/files
locale: ru
description: "Как получить ссылку на файл заказа, где лежат субтитры и сколько хранятся файлы."
updated: 2026-10-18
sources: [get-orders-order, post-storage-url, post-orders-order-retry]
errors: ["404", storage-expired, "403"]
spec_version: 1.0.0
---

# Файлы, ссылки и хранение

Готовый заказ отдаёт результат в `result.files[]`. Там лежат пути внутри хранилища, а не
ссылки, и `GET` по такой строке ничего не вернёт. Скачивание идёт в два шага: сначала путь
меняется на временную ссылку, затем файл скачивается по ней.

## Обмен пути на ссылку

| Поле | Правило | По умолчанию | Назначение |
| --- | --- | --- | --- |
| `path` | обязательное, строка | — | Строка из `result.files[]` или `result.service_files[]` |
| `download` | boolean | `false` | `true` помечает ссылку как вложение: файл сохранится под именем заказа (`Order.name`), а не откроется во вкладке |
| `number_base` | integer, `0` или `1` | `1` | С какого числа нумеруются чанки в имени файла |
| `number_padding` | integer, `1..4` | `3` | Ширина номера чанка с ведущими нулями: при `3` получится «007» |

`POST /storage/url` принимает путь целиком, как он записан в заказе, и возвращает в `data.url`
подписанную временную ссылку. Это единственная операция, которой нужно
[право `orders.download`](/developers/docs/guide/authentication). Ключ с правами `orders.read`
и `orders.write` видит заказ, но на запрос ссылки получает `403` без поля `reason`.

Ссылка действует около часа. Файл по ней скачивается обычным `GET` без заголовка `X-API-KEY`:
подпись уже входит в URL. Не сохраняйте ссылку надолго, запрашивайте её перед скачиванием.
Если ссылка истекла, снова вызовите `POST /storage/url` с тем же путём. Сам файл от этого не
меняется.

### POST /storage/url

Ссылка на файл

Справочник: https://lumean.app/developers/docs/api/post-storage-url

## Основные и служебные файлы

| Поле | Что внутри |
| --- | --- |
| `result.files[]` | Основной результат. У озвучки после склейки — один элемент, финальная дорожка. У `music` — по файлу на каждый вариант из `n_variants` |
| `result.service_files[]` | Субтитры `.srt`, `.vtt`, `.lrc`, выравнивание и `result.json` с таймингами слов |

Оба поля — плоские массивы строк-путей. Субтитры и выравнивание лежат только в
`service_files[]`.

Служебные файлы создают только TTS-сервисы. Ключ `service_files` приходит, только если набор
не пуст. У `sfx` и `music` его нет совсем: не `null` и не `[]`, а отсутствующий ключ. Поэтому
проверяйте наличие ключа.

`service_files` есть только у заказа. `GET /orders/{order}/items/{item}` отдаёт только
`result_file` самого чанка.

Отдельного поля с типом файла нет. Тип определяется по расширению и по сегменту `/service/`
в пути. Пути `raw_chunk` и `metadata` по ключу не видны, а запрос ссылки на них возвращает
`403`.

## Скачивание всех файлов заказа

```text
Конвейер публичного API

Один раз:
  Ключ        X-API-KEY            заголовок в каждом запросе
    ↓
  Права       orders.write         пресет ключа задаёт доступные операции
    ↓
  Голос       GET /voices          voice_id из каталога
    ↓
  Шаблон      POST /templates      voice_id хранится в config.tts_settings

Каждый заказ:
  Шаблон      template_id          готовый шаблон из настройки
    ↓
  Заказ       POST /orders         201, статус created, результата ещё нет
    ↓
  Ожидание    GET /orders/{order}  статус, пока заказ не завершится
    ↓
  Файлы       result.files[]       пути в хранилище, а не ссылки
    ↓
  Ссылка      POST /storage/url    путь → ссылка на скачивание
```

```bash
# 1. Заказ: пути лежат в result, статус должен быть терминальным
curl -s "$BASE/orders/$ORDER_ID" -H "X-API-KEY: $KEY"

# 2. Каждый путь из files[] и из service_files[] меняется на ссылку
curl -s -X POST "$BASE/storage/url" -H "X-API-KEY: $KEY" -H "Content-Type: application/json" \
  -d '{ "path": "storage/501/orders/<ORDER_UUID>/output/final/result.mp3", "download": true }'
# → { "success": true, "data": { "url": "https://s3.lumean.app/…?X-Amz-Signature=…" } }

# 3. Файл скачивается по data.url обычным GET, без X-API-KEY
curl -sL -o result.mp3 "$URL"
```

У заказа в статусе [`partially_completed`](/developers/docs/guide/async) файлы тоже можно
забрать: успешные фрагменты уже готовы. У заказов `failed` и `compensated` файлов нет.

## Срок хранения

Файлы заказа удаляются через 7 дней после перехода в терминальный статус: `completed`,
`result_delivered`, `failed`, `compensated` или `cancelled`. Это срок по умолчанию. Если заказ
склеен в отдельный финальный файл, дорожки отдельных фрагментов удаляются раньше, по умолчанию
через 48 часов. Сроки видны в ответе `GET /orders/{order}`:

| Поле | Значение |
| --- | --- |
| `files_expire_at`, `retention.files.expires_at` | Когда будут удалены все файлы заказа. `null` — заказ ещё не терминальный или файлы уже удалены |
| `files_expired`, `retention.files.expired` | `true` — файлов больше нет, ссылку получить нельзя |
| `retention.chunks.expires_at`, `retention.chunks.expired` | Срок дорожек фрагментов. Пока они есть, доступны правка пауз, пересборка финала, перегенерация и повтор чанка |
| `retention.chunks.expires_early` | `true` — фрагменты будут удалены раньше результата, потому что заказ склеен в отдельный файл |
| `retention.chunks.reason` | `chunks_purged` — фрагментов нет, результат на месте. `storage_expired` — файлов нет совсем. `null` — всё доступно |

> [!WARNING]
> После удаления файлов `GET /orders/{order}` по-прежнему возвращает пути в `result.files[]`.
> Путь в ответе не означает, что файл существует. Проверяйте `files_expired` или
> `retention.files.expired`. На путь к удалённому файлу `POST /storage/url` отвечает `404`.

### 404 · `storage_expired` — storage_expired — срок хранения файлов истёк

| Что произошло | Что делать |
| --- | --- |
| Файлы заказа удалены. `POST /storage/url` на путь из `result.files[]` отвечает 404 `{"success": false, "message": "File not found."}`. То же имя бывает значением поля в ответе превью чанков. Другое значение этого поля — `chunks_purged`: удалены только фрагменты, а результат ещё на месте. | `GET /orders/{order}` и после удаления показывает пути в `result.files[]`. Удалены ли файлы, показывает `files_expired` (и `retention.files.expired`), срок удаления — `files_expire_at`. Восстановить удалённые файлы нельзя. Скачивайте результат сразу после `completed`. Субтитры лежат отдельно, в `result.service_files[]`, и удаляются вместе с остальными файлами. |

`Retry-After`: нет. Разбор: https://lumean.app/developers/docs/errors/storage-expired

Удалённые файлы не восстанавливаются. Запись заказа остаётся, но самих файлов больше нет.
Получить результат заново можно только через
[`POST /orders/{order}/retry`](/developers/docs/api/post-orders-order-retry). Он работает для
заказов в статусе `completed` и `result_delivered`, создаёт новый заказ с теми же параметрами,
и этот заказ оплачивается заново.

**Правильно**

Скачать `files[]` и `service_files[]` сразу после `completed`. Перед скачиванием старого заказа
проверить `files_expired`.

**Неправильно**

Хранить пути или ссылки как постоянные адреса. Ссылка истекает через час, файлы удаляются через
неделю, а путь остаётся в ответе и после этого.

---

- Эта же страница в браузере: https://lumean.app/developers/docs/guide/files
- Машинный справочник целиком: https://api.lumean.app/docs/llm.md
