# Генерация и экспорт PPT

Создавайте презентацию, опрашивайте ее ход, экспортируйте PPTX и управляйте сроком ее жизни.

Генерируйте презентацию асинхронно, затем экспортируйте файл PPTX. Разделяйте шаги генерации и экспорта: созданная задача — это еще не готовый файл.

Во всех примерах используется `FELO_API_KEY` из [обзора](https://openapi.felo.ai/ru/docs/data-api/guides/felo-overview.md). Вызовы используют **баланс платформы**, а не кредиты Felo Pro. Примеры ответов носят иллюстративный характер; фактический контент и необязательные поля могут отличаться.

## Рабочий процесс и идентификаторы

1. Создайте задачу генерации; сохраните `task_id`, `ppt_business_id` и `expires_at`.
2. Опрашивайте статус генерации, используя `task_id`.
3. Читайте результаты генерации, используя `task_id`.
4. Запустите экспорт PPTX, используя `ppt_business_id`.
5. Опрашивайте статус экспорта и загрузите готовый файл.
6. При необходимости удалите презентацию досрочно.

В заполнителях маршрута `{business_id}` означает возвращенный **`ppt_business_id`**, а не `task_id`, `resource_id` или `livedoc_short_id`. Используйте одну и ту же учетную запись API на всем протяжении рабочего процесса. Идентификаторы в примерах являются заполнителями.

## 1. Создайте презентацию

`POST /api/v1/data/ppts`

| Поле | Тип | Обязательно | Значение |
|---|---|---|---|
| `query` | string | Да | Инструкции для генерации, 1–25,000 символов |
| `stream_protocol` | string | Нет | По умолчанию `message_center_v1`; обычно оставляйте без изменений |
| `ppt_config` | object | Нет | Необязательная конфигурация; текущая реализация читает `ai_theme_id` |
| `livedoc_short_id` | string | Нет | ID существующего контекста, до 100 символов; должен проходить встроенные проверки API на владение и срок действия |
| `resource_ids` | string array | Нет | До 100 UUID resource IDs; подлежат тем же проверкам доступа к контексту |

Для первой интеграции опустите поля контекста и конфигурации. Контекст, созданный через `/v2`, не может автоматически повторно использоваться здесь.

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/ppts" \
  -H "Authorization: Bearer $FELO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query":"Create a 5-slide introduction to retrieval augmented generation for software developers."}'
```

HTTP 200 возвращает идентификаторы в корне:

```json
{
  "task_id":"example-task-id",
  "ppt_business_id":"example-ppt-id",
  "livedoc_short_id":"example-livedoc-id",
  "expires_at":"2026-11-13T00:00:00Z"
}
```

Дополнительные идентификаторы, такие как `resource_id`, `stream_key` и `thread_short_id`, могут присутствовать. Успешный ответ create означает, что задача принята, но не что генерация завершена. Запрошенное число слайдов — это инструкция; биллинг использует фактическое количество сгенерированных страниц.

```bash
TASK_ID="example-task-id"
PPT_ID="example-ppt-id"
```

### Читайте события генерации через SSE

Если при создании возвращается `stream_key`, подключитесь немедленно с API key, принадлежащим той же учетной записи. Если stream_key не возвращен, используйте запросы статуса и результатов ниже.

```bash
curl -N 'https://openapi.felo.ai/api/v1/data/conversations/stream/YOUR_STREAM_KEY?format=structured' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: text/event-stream'
```

| Параметр запроса | Значение |
|---|---|
| `format` | `raw` (по умолчанию) сохраняет строку `content`; `structured` декодирует допустимый JSON в объект или массив |
| `offset` | Необязательная позиция возобновления на вышестоящем сервисе для переподключения; не выводите ее из числа локальных событий |

Читайте каждое полное SSE-событие, декодируйте его внешний JSON, затем обрабатывайте `content`. Событие приложения `answer` несет текст в `data.text`; `finished` сигнализирует о завершении генерации в потоке. Также обрабатывайте сигналы вышестоящего `done`, `[DONE]` и `error`. Если соединение закрывается без сигнала завершения, запросите статус задачи.

Используйте правила разбора и пример клиента из [SuperAgent SSE](https://openapi.felo.ai/ru/docs/api-reference/superagent.md#2-sse), с URL этого раздела `/api/v1/data/conversations/stream/{stream_key}`. Читайте результат задачи после окончания потока; экспорт PPTX остается отдельным шагом. Эта конечная точка не включает `stream: true` для `/api/v1/data/chat`.

## 2. Опрашивайте статус генерации

`GET /api/v1/data/tasks/{task_id}/status`

```bash
curl -sS --request GET "https://openapi.felo.ai/api/v1/data/tasks/$TASK_ID/status" \
  -H "Authorization: Bearer $FELO_API_KEY"
```

В ответе есть корневая строка `status`, например `RUNNING` или `COMPLETED`. Опрашивайте с ограниченным интервалом (например, 2–5 секунд) и дедлайном. После завершения переходите к результатам; обрабатывайте сбой и неожиданные статусы, не предполагая успеха. Дедлайн опроса не отменяет задачу.

```json
{"status":"COMPLETED"}
```

## 3. Читайте результаты генерации

`POST /api/v1/data/tasks/{task_id}/historical`

Это **POST**, JSON-тело не требуется.

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/tasks/$TASK_ID/historical" \
  -H "Authorization: Bearer $FELO_API_KEY"
```

```json
{
  "task_id":"example-task-id",
  "task_status":"COMPLETED",
  "history_data":{},
  "error_message":null
}
```

Сначала прочитайте `task_status`, прежде чем использовать `history_data`. Историческая полезная нагрузка может различаться по задаче и может быть null. `ai_page_html` и `thread_short_id` необязательны. Этот ответ не является гарантированным URL для загрузки PPTX; далее используйте экспорт.

## 4. Запустите экспорт PPTX

`POST /api/v1/data/ppts/{business_id}/export`

```bash
curl -sS --request POST "https://openapi.felo.ai/api/v1/data/ppts/$PPT_ID/export" \
  -H "Authorization: Bearer $FELO_API_KEY"
```

```json
{"status":"PROCESSING","download_url":null,"expires_at":null}
```

Генерация должна быть завершена до экспорта. Повторный POST во время выполнения того же экспорта переиспользует его. Запуск другого экспорта после завершения создает новый экспорт и может привести к дополнительному списанию. Используйте GET для опроса и обновления ссылки на загрузку.

## 5. Опросите экспорт и загрузите файл

`GET /api/v1/data/ppts/{business_id}/export`

```bash
curl -sS --request GET "https://openapi.felo.ai/api/v1/data/ppts/$PPT_ID/export" \
  -H "Authorization: Bearer $FELO_API_KEY"
```

| Статус | Следующее действие |
|---|---|
| `NOT_STARTED` | Отправьте экспорт один раз |
| `PROCESSING` | Подождите, затем снова опросите GET |
| `COMPLETED` | Прочитайте `download_url` и загрузите файл |
| `FAILED` | Изучите ошибку и состояние задачи перед отправкой нового экспорта |

```json
{
  "status":"COMPLETED",
  "download_url":"https://example.com/presentation.pptx?signature=example",
  "expires_at":"2026-11-06T00:30:00Z"
}
```

Пример URL носит иллюстративный характер. Используйте фактический подписанный URL из ответа. Он действителен **30 минут**; GET статуса экспорта может вернуть новую ссылку, пока презентация остается доступной. Сохраните файл в пределах срока его действия. Не отправляйте свой Felo API key хосту загрузки файла.

## 6. Удалите презентацию

`DELETE /api/v1/data/ppts/{business_id}`

```bash
curl -sS --request DELETE "https://openapi.felo.ai/api/v1/data/ppts/$PPT_ID" \
  -H "Authorization: Bearer $FELO_API_KEY"
```

Успех возвращает **HTTP 204 без тела**. Не пытайтесь разобрать его как JSON. Удаление во время выполнения генерации возвращает 409.

## Срок жизни, владение и биллинг

- Презентации истекают **через семь дней после создания**. Запросы и экспорты не продлевают этот срок. `expires_at` презентации и `expires_at` подписанного URL загрузки описывают разные сроки жизни.
- Только API-аккаунт, создавший презентацию, может получать доступ к своим задачам и презентациям. Отсутствующий или недоступный ресурс может вернуть 404; просроченный или удаленный ресурс может вернуть 410, либо 404 после очистки.
- Генерация тарифицируется за каждую сгенерированную страницу (`ppt.generate`). При тарификации по страницам создание резервирует стоимость десяти страниц, затем окончательно учитывает фактически успешный результат и освобождает неиспользованный резерв. На вашем аккаунте должно быть достаточно доступного баланса для резерва, даже если в запросе указано меньше страниц.
- Экспорт имеет отдельную цену за запрос (`ppt.export`). Запросы статуса, запросы результатов, запросы статуса экспорта и удаление не создают нового списания.
- После тайм-аута запросите сохраненную задачу, а не создавайте другую презентацию. См. [Биллинг и ошибки](https://openapi.felo.ai/ru/docs/data-api/guides/felo-billing.md).
