Upload an eBook PDF

Publishes your own eBook PDF in three steps: signed URL, PUT to S3 and confirmation.


Upload an eBook PDF

Publishes an eBook PDF you produced yourself, instead of generating the content with AI. The file does not go through the Panda API: you request a signed S3 URL, send the file straight to it, and then confirm.

Every call on this page uses the POST /aiworkflow/aipackage route, varying the action field in the body.

📘

Authorization

Calls to the Panda API require the API key in the Authorization header, without the Bearer prefix. The PUT of the file to the signed URL does not carry your API key — the authorization is already embedded in the URL.

The three steps

#CallWhat happens
1POST /aiworkflow/aipackage with action: upload_abstract_urlReturns the signed URL and the file key
2PUT of the PDF straight to the returned URLThe file reaches S3
3POST /aiworkflow/aipackage with action: confirm_abstractThe eBook is published in that language

Step 1 — request the signed URL

Body:

FieldTypeRequiredDescription
actionstringYesupload_abstract_url
video_idstring (uuid)YesVideo the eBook belongs to
langstringYesLanguage of the eBook (e.g. pt-BR)
{ "action": "upload_abstract_url", "video_id": "{video_id}", "lang": "pt-BR" }

Response (200):

{ "url": "https://...", "key": "...", "expires_in": 3600 }
FieldTypeContent
urlstringSigned S3 URL — this is where you PUT the file
keystringPath of the object in storage
expires_inintegerValidity of the URL in seconds (3600 = 1 hour)
⚠️

The field is url, not upload_url.

This has already happened in production: the client read upload_url, got undefined, sent the PUT to the wrong host, received a 200 from a server that was not S3, and only found out at step 3, which failed with "Uploaded PDF not found". A 200 at step 2 does not prove the file reached the right place — make sure the URL you use is exactly the one returned in url.

⚠️

The URL expires in 1 hour (expires_in: 3600). If the upload takes longer than that, request a new one before retrying.

Step 2 — send the file

PUT the PDF straight to the URL from step 1, without the Authorization header:

curl -X PUT "{url_from_step_1}" \
  -H "Content-Type: application/pdf" \
  --data-binary "@my-ebook.pdf"

Step 3 — confirm and publish

Body:

FieldTypeRequiredDescription
actionstringYesconfirm_abstract
video_idstring (uuid)YesThe same video from step 1
langstringYesThe same language from step 1
upload_successbooleanYestrue to publish the uploaded file
{ "action": "confirm_abstract", "video_id": "{video_id}", "lang": "pt-BR", "upload_success": true }

After the confirmation, the eBook shows up in config.ai.resources[] in GET /videos/{video_id}, with type: abstract and the srclang of the language you sent.

⚠️

If step 2 did not put the file on the signed URL, step 3 fails with "Uploaded PDF not found". Start over from step 1.

eBook images

Two actions of the same route return a signed URL for images. The flow is the same: request the URL, PUT the file, and use the key that comes back.

upload_logo_url — cover logo

FieldTypeRequiredDescription
actionstringYesupload_logo_url
video_idstring (uuid)YesVideo
content_typestringYesMIME type of the file (e.g. image/png)

The returned key is the value of logo_key in abstract_config — see Generate an AI Resource.

upload_abstract_image_url — image inserted in the editor

FieldTypeRequiredDescription
actionstringYesupload_abstract_image_url
video_idstring (uuid)YesVideo
langstringYesLanguage of the eBook
content_typestringYesMIME type of the file (e.g. image/jpeg)

To generate an image with AI instead of uploading your own, see Generate an AI Image.

Example Usage

cURL — full flow

# 1) request the signed URL
curl -X POST "https://api-v2.pandavideo.com.br/aiworkflow/aipackage" \
  -H "Authorization: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{ "action": "upload_abstract_url", "video_id": "{video_id}", "lang": "pt-BR" }'

# 2) send the file to the URL returned in "url" (no Authorization)
curl -X PUT "{url}" \
  -H "Content-Type: application/pdf" \
  --data-binary "@my-ebook.pdf"

# 3) confirm
curl -X POST "https://api-v2.pandavideo.com.br/aiworkflow/aipackage" \
  -H "Authorization: {api_key}" \
  -H "Content-Type: application/json" \
  -d '{ "action": "confirm_abstract", "video_id": "{video_id}", "lang": "pt-BR", "upload_success": true }'