One route, several operations: the action field in the body selects create, regenerate, allow download or request an upload URL.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
POST /aiworkflow/aipackage
One route, several operations. The action field — sent in the request body — selects what the call does: create a resource by hand, regenerate it, allow its download, or request a signed upload URL.
Naming: abstract = eBook, mindmap = Mind Map, questions = Quiz.
actiongoes in the BODY, not in the query stringUnlike other routes of this API that dispatch on
?action=, here the field is part of the JSON. Sending?action=regeneratein the URL has no effect — the call falls through to the behaviour withoutaction, which generates the whole package in the old model (and consumes credits).
AuthorizationRequires the account API key in the
Authorizationheader, without theBearerprefix.
Available Operations
action | What it does | Body fields | Consumes credits |
|---|---|---|---|
create | Creates a Mind Map or Quiz by hand, without AI | video_id, lang, resource, questions, questions_config, mindmap | No |
regenerate | Deletes and regenerates the resource in the same language, in one call | video_id, resource, lang + the *_config objects | Yes |
set_download | Turns the download of that resource on or off | video_id, resource, allow_download | No |
upload_abstract_url | Returns a signed S3 URL to upload an eBook PDF | video_id, lang | No |
confirm_abstract | Confirms the upload and publishes the uploaded eBook | video_id, lang, upload_success | No |
upload_logo_url | Signed URL for the eBook cover logo | video_id, content_type | No |
upload_abstract_image_url | Signed URL for an image inserted in the editor | video_id, lang, content_type | No |
| (absent) | Generates the whole package in the old model (compatibility) | video_id, from_lang, type: ALL_TEXT_ITEMS | Yes |
The four upload actions are detailed on Upload an eBook PDF.
Two operations of the same route use other HTTP methods and have their own page:
| Method | What it does | Page |
|---|---|---|
PUT | Saves the edited content of a resource, per language | Save AI Resource Content |
DELETE | Removes one resource from one language | Delete an AI Resource |
HTTP Method & Path
POST /aiworkflow/aipackage
Base URL: https://api-v2.pandavideo.com.br
Authentication Requirements
| Item | Value |
|---|---|
| Security Scheme | API Key |
| Header | Authorization |
| Format | The raw key, without Bearer |
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Authorization | header | string | Yes | Account API key |
Request Body
Content-Type: application/json
video_id is required by every action. The remaining fields depend on the action.
action: create — create a resource by hand
action: create — create a resource by handCreates a Mind Map or a Quiz with the content you send, without going through the AI and without consuming credits. Useful to import material you already have.
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | create |
video_id | string (uuid) | Yes | Video the resource belongs to |
lang | string | Yes | Language of the resource (e.g. pt-BR) |
resource | string | Yes | mindmap or questions |
questions | array | Conditional | Questions, when resource is questions |
questions_config | object | No | Quiz behaviour |
mindmap | object | Conditional | Map tree, when resource is mindmap |
{
"action": "create",
"video_id": "{video_id}",
"lang": "pt-BR",
"resource": "questions",
"questions": [
{
"enunciate": "Which vitamin is synthesised through sun exposure?",
"options": [
{ "text": "Vitamin A", "correct": false },
{ "text": "Vitamin D", "correct": true }
]
}
],
"questions_config": { "num_answers": 2, "allow_skip": false }
}action: regenerate — regenerate in the same language
action: regenerate — regenerate in the same languageDeletes the resource and generates it again, in the same language, in a single call. Consumes credits.
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | regenerate |
video_id | string (uuid) | Yes | Video |
resource | string | Yes | abstract, mindmap or questions |
lang | string | Yes | Language of the resource to regenerate |
abstract_config | object | No | eBook layout |
mindmap_config | object | No | Mind Map appearance |
questions_config | object | No | Quiz behaviour |
An omitted config field reuses the one from the previous generation — it does not reset to defaults.If the eBook was generated with
layout: magazineand you regenerate without sendingabstract_config, it comes outmagazineagain. To go back to defaults, send the object with the values you want explicitly.
{
"action": "regenerate",
"video_id": "{video_id}",
"resource": "abstract",
"lang": "en",
"abstract_config": { "layout": "modern", "accent_color": "#3F55EE" }
}action: set_download — allow or block the download
action: set_download — allow or block the download| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | set_download |
video_id | string (uuid) | Yes | Video |
resource | string | Yes | abstract, mindmap or questions |
allow_download | boolean | Yes | true allows, false blocks |
{
"action": "set_download",
"video_id": "{video_id}",
"resource": "abstract",
"allow_download": true
}Response (200):
{ "status": "updated", "resource": "abstract", "allow_download": true }
The permission is per resource, not per language. Allowingabstractapplies to all languages of that video's eBook. You cannot allow the English eBook while keeping the Portuguese one blocked.The flag is stored in
config.ai.allow_downloadofGET /videos/{video_id}, keyed by resource — for example{ "abstract": true, "questions": false }.
set_downloaddoes not check whether the resource exists. Calling it for a resource the video does not have still returns200and stores the flag, which then applies if that resource is created later. Do not use this call to test whether a resource exists — readconfig.ai.resources[]instead.
Without action — whole package, old model
action — whole package, old modelKept for backward compatibility. Generates eBook, Mind Map and Quiz together, in one language, in the v1 format (a file without a language suffix).
| Field | Type | Required | Description |
|---|---|---|---|
video_id | string (uuid) | Yes | Video |
from_lang | string | No | Audio language |
type | string | No | ALL_TEXT_ITEMS |
For new content, preferPOST /aiworkflow, which generates one resource at a time and accepts several languages into_langs, writingschema_version: 2in the output file.
Response
The response body depends on the action — the upload actions return the signed URL, set_download returns the updated state, and create and regenerate return the job that was created.
Error Responses
400: unknownaction, a field required by the chosen action is missing, or an unknown field inside a*_config(strict object).401: missing or invalid API key.402: not enough AI credits (regenerateand package generation).404: video not found. Note thatset_downloaddoes not return404for a resource that does not exist — see the warning above.500: internal error.
Validation errors come back as { "errCode": "BadRequest", "errMsg": "..." }, and errMsg names the offending field.
Example Usage
cURL
# Allow the eBook download
curl -X POST "https://api-v2.pandavideo.com.br/aiworkflow/aipackage" \
-H "Authorization: {api_key}" \
-H "Content-Type: application/json" \
-d '{
"action": "set_download",
"video_id": "{video_id}",
"resource": "abstract",
"allow_download": true
}'
# Regenerate the Portuguese Quiz
curl -X POST "https://api-v2.pandavideo.com.br/aiworkflow/aipackage" \
-H "Authorization: {api_key}" \
-H "Content-Type: application/json" \
-d '{
"action": "regenerate",
"video_id": "{video_id}",
"resource": "questions",
"lang": "pt-BR",
"questions_config": { "num_questions": 5, "num_answers": 4 }
}' 401Missing or invalid API key.
402Not enough AI credits.
404Video or resource not found.
500Internal error.
