Configure Harness
PPT Task API
Create PPT generation tasks, list themes, and poll shared task endpoints.
/v2/pptsAuthentication
Bearer API key
Content type
application/json
Rate notes
Endpoint-specific limits may apply.
The PPT Task API provides asynchronous PPT generation capabilities. You can create a task and then poll task status by task_id. You can also browse available PPT themes and apply them when creating tasks.
Authentication
All requests require an API Key in the Authorization header:
Authorization: Bearer YOUR_API_KEYUse with AI Agents
To create slides from an Agent, install the complete felo-ai package rather than a fixed subset of Skills. Its installer dynamically discovers every package directory containing SKILL.md, including the PPT Skill and future additions. Install all discovered Skills in the native directory for your Agent: Codex ~/.codex/skills, Claude Code ~/.claude/skills, OpenClaw ~/.agents/skills, or Hermes Agent ~/.hermes/skills. Follow the manual AI Agent setup guide for platform-specific API key configuration and verification.
1. List PPT Themes
Query available PPT themes with pagination, keyword search, language and type filtering.
Endpoint
GET https://openapi.felo.ai/v2/ppt-themesQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
lang | string | No | Language code for localized content (e.g. en, zh-Hans). Default: en |
type | string | No | Filter by theme type (e.g. default, custom) |
keyword | string | No | Search keyword, matches theme titles |
page | integer | No | Page number, starting from 1. Default: 1 |
size | integer | No | Page size, max 100. Default: 20 |
Example
curl -X GET 'https://openapi.felo.ai/v2/ppt-themes?lang=en&page=1&size=10' \
-H 'accept: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY'Success Response (200)
{
"status": "ok",
"message": null,
"data": {
"total": 8,
"page": 1,
"size": 10,
"items": [
{
"id": "43122897-0d3c-4c9e-ae19-20527ad36c04",
"title": "Inspiration Themes",
"subtitle": "AI-tailored visual solutions",
"description": "Style and layout, both crafted by AI from your content in real time"
}
]
}
}Theme Response Fields
| Field | Type | Description |
|---|---|---|
total | integer | Total number of themes matching the filter |
page | integer | Current page number |
size | integer | Page size |
items | array | List of theme objects |
items[].id | string | Theme ID, use this as ai_theme_id when creating PPT |
items[].title | string | Theme title (localized) |
items[].subtitle | string | Theme subtitle (localized) |
items[].description | string | Theme description (localized) |
2. Create PPT Task
Endpoint
POST https://openapi.felo.ai/v2/pptsRequest Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Your API Key in the format Bearer YOUR_API_KEY |
Content-Type | Yes | application/json or multipart/form-data |
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | PPT generation request prompt |
livedoc_short_id | string | No | Existing LiveDoc short ID to associate with the PPT session. If omitted, a new LiveDoc is created automatically. |
resource_ids | array of strings | No | List of LiveDoc resource IDs to use as context for PPT generation |
ppt_config | object | No | PPT configuration options |
ppt_config.ai_theme_id | string | No | Theme ID from the List PPT Themes endpoint |
Example
curl -X POST 'https://openapi.felo.ai/v2/ppts' \
-H 'accept: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "Felo, 2 pages",
"ppt_config": {
"ai_theme_id": "02968979-a69f-42c4-b136-de02c40ab2d7"
}
}'Create from an Uploaded File
Use multipart/form-data to upload one file and create a PPT task in a single request. The platform uploads the file as a LiveDoc resource first, then passes its resource ID to the PPT task.
| Part | Type | Required | Description |
|---|---|---|---|
query | string | Yes | PPT generation request prompt |
file | file | Yes | Source file used as PPT context |
stream_protocol | string | No | Streaming protocol; defaults to message_center_v1 |
livedoc_short_id | string | No | Existing LiveDoc to receive the file. A new LiveDoc is created when omitted. |
ppt_config | JSON | No | PPT configuration with the same structure as the JSON request body. Send this part as application/json. |
curl -X POST 'https://openapi.felo.ai/v2/ppts' \
-H 'accept: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'query=Create a 10-page presentation based on this report' \
-F 'ppt_config={"ai_theme_id":"02968979-a69f-42c4-b136-de02c40ab2d7"};type=application/json' \
-F '[email protected]'The response uses the same schema as the JSON request. The returned livedoc_short_id identifies the LiveDoc containing the uploaded resource.
Success Response (200)
{
"status": "ok",
"message": null,
"data": {
"livedoc_short_id": "PvyKouzJirXjFdst4uKRK3",
"ppt_business_id": "BfLPuQKmChk9SPmyQawxgr",
"task_id": "019cad6d-e874-55ef-d577-686344b5a7e9"
}
}3. Query Task Status
Endpoint
GET https://openapi.felo.ai/v2/tasks/{task_id}/statusExample
curl -X GET 'https://openapi.felo.ai/v2/tasks/019cad6d-e874-55ef-d577-686344b5a7e9/status' \
-H 'accept: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY'Success Response (200)
{
"status": "ok",
"message": null,
"data": {
"status": "RUNNING"
}
}4. Query Task Historical Info
Endpoint
GET https://openapi.felo.ai/v2/tasks/{task_id}/historicalExample
curl -X GET 'https://openapi.felo.ai/v2/tasks/019cb17e-9e23-3d40-4447-48a651249460/historical' \
-H 'accept: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY'RUNNING Response
{
"status": "ok",
"message": null,
"data": {
"task_id": "019cb17e-9e23-3d40-4447-48a651249460",
"task_status": "RUNNING",
"ppt_biz_id": "oM8A9iJHg8dT4ZKgHThQTx",
"ppt_url": "https://felo.ai/slides/oM8A9iJHg8dT4ZKgHThQTx"
}
}COMPLETED Response
{
"status": "ok",
"message": null,
"data": {
"task_id": "019cb17e-9e23-3d40-4447-48a651249460",
"task_status": "COMPLETED",
"ppt_biz_id": "oM8A9iJHg8dT4ZKgHThQTx",
"ppt_url": "https://felo.ai/slides/oM8A9iJHg8dT4ZKgHThQTx",
"live_doc_short_id": "oM8A9iJHg8dT4ZKgHThQTx",
"live_doc_url": "https://felo.ai/livedoc/oM8A9iJHg8dT4ZKgHThQTx"
}
}COMPLETED Response (AI_PAGE)
{
"status": "ok",
"message": null,
"data": {
"task_id": "019d7a4d-6ab5-a96d-0f98-43ca434ab621",
"task_status": "COMPLETED",
"ppt_biz_id": "9qiLTmT77fA3aVurrMHvRJ",
"ppt_url": "https://felo.ai/slides/9qiLTmT77fA3aVurrMHvRJ",
"ai_page_html": "https://felo.ai/ai-page/9qiLTmT77fA3aVurrMHvRJ"
}
}FAILED / PENDING / EXPIRED / CANCELED Response
{
"status": "ok",
"message": null,
"data": {
"task_id": "019cb17e-9e23-3d40-4447-48a651249460",
"task_status": "FAILED",
"ppt_biz_id": "oM8A9iJHg8dT4ZKgHThQTx",
"ppt_url": "https://felo.ai/slides/oM8A9iJHg8dT4ZKgHThQTx",
"error_message": "PPT generation failed",
"live_doc_short_id": "oM8A9iJHg8dT4ZKgHThQTx",
"live_doc_url": "https://felo.ai/livedoc/oM8A9iJHg8dT4ZKgHThQTx"
}
}Historical Response Fields
| Field | Type | Description |
|---|---|---|
task_id | string | Task ID |
task_status | string | Current task status |
ppt_biz_id | string | PPT business ID (mapped from backend thread_short_id) |
ppt_url | string | PPT URL, format: https://felo.ai/slides/{ppt_biz_id} |
error_message | string | Present for FAILED / PENDING / EXPIRED / CANCELED; empty string "" when downstream does not provide error details |
ai_page_html | string | Present when the task runs in AI_PAGE mode and downstream historical returns an HTML result URL |
live_doc_short_id | string | LiveDoc short ID. For COMPLETED it comes from downstream live_doc_short_id; for terminal failure statuses it is returned when available |
live_doc_url | string | LiveDoc URL corresponding to live_doc_short_id |
Polling Recommendation
Use task_id from create response and poll status every 2-5 seconds until the status becomes a terminal state.
Common status examples:
RUNNING: task is still processingCOMPLETED: task completed successfullyFAILED/PENDING/EXPIRED/CANCELED: task reached terminal status witherror_message;live_doc_urlis also returned when available
Unknown status values may appear as backend evolves; treat them as non-terminal unless documented otherwise.
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
INVALID_API_KEY | 401 | API Key is invalid or revoked |
PPT_TASK_CREATE_FAILED | 502 | Create task downstream call failed |
PPT_TASK_QUERY_FAILED | 502 | Query task status downstream call failed |