For the complete documentation index, see llms.txt. This page is also available as Markdown.

POST /generator/create-async

Use this endpoint to create a presentation from a .pptx template file and JSON data without waiting for the file on the same connection. The API accepts your request, returns a job ID immediately, and builds the presentation in the background. You then poll jobs/{jobId}/status until the job finishes and download the result from the link it returns.

Synchronous or asynchronous?

Both endpoints take exactly the same files and jsonData payload, use the same token, and count towards the same usage allowance. If a synchronous call is timing out, moving to the asynchronous endpoint is a drop-in change on the request side — you only add the polling step.

generator/create-async

(v2.0)

Style

Synchronous — one request

Asynchronous — submit, then poll

Response

The .pptx file as a binary stream

JSON containing a job ID

Connection held open

For the whole generation

Only long enough to upload the template and JSON

Best for

Small and medium decks, quick interactive calls

Large decks — many slides, large tables, charts and images

Risk

Client, proxy or gateway timeouts on long jobs

None — generation time is decoupled from the request

1

Submit the job

generator/create-async

POST https://gen.powerpointgeneratorapi.com/v2.0/generator/create-async

Headers

Name
Type
Description

Content-Type*

String

multipart/form-data

Authorization*

String

Bearer authentication token

Request Body

Name
Type
Description

files*

File or array of files

.pptx template file(s), plus any image files

jsonData*

String

JSON data

The job has been queued. Keep the job_id — you need it to check the status and collect the file.

{
  "job_id": "3f9c1a72-58d4-4f0e-9a7b-2c6d0b1e84af",
  "status": "QUEUED"
}

A successful submission may be returned as either 200 OK or 202 Accepted. Treat both as success.

Returns a JSON error object describing what was invalid.

{
    "statusCode": 400,
    "message": "Invalid input parameters",
    "details": "{more information}",
}
{
  "statusCode": 401,
  "message": "Unauthorized",
  "detail": "The bearer token is missing, expired, or invalid."
}
{
  "statusCode": 429,
  "message": "Too Many Requests - usage or rate limit exceeded",
  "detail": "Too many requests: monthly slide limit exceeded."
}
2

Check the job status

jobs/{jobId}/status

GET https://gen.powerpointgeneratorapi.com/v2.0/jobs/{jobId}/status

Path Parameters

Name
Type
Description

jobId*

String

The job_id returned by generator/create-async

Headers

Name
Type
Description

Authorization*

String

Bearer authentication token

A job moves through QUEUED → PROCESSING → SUCCEEDED or FAILED.

Status
Meaning

QUEUED

Accepted and waiting to be picked up. Keep polling.

PROCESSING

The presentation is being generated. Keep polling.

SUCCEEDED

The presentation is ready to download. Stop polling.

FAILED

Generation failed. error_message explains why. Stop polling.

While the job is running

{
  "status": "PROCESSING",
  "error_message": null,
  "file_url": null
}

When the job has succeeded

{
  "status": "SUCCEEDED",
  "error_message": null,
  "file_url": "https://pptx-gen-async.s3.eu-west-1.amazonaws.com/jobs/3f9c1a72-58d4-4f0e-9a7b-2c6d0b1e84af/result/quick_start_example.pptx?X-Amz-Expires=900&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Date=20260829T131247Z&X-Amz-SignedHeaders=host&X-Amz-Signature=..."
}

Download the presentation from file_url. It is a pre-signed link generated by the API — use it exactly as returned rather than constructing it yourself. The file is named after the resultFileName in your jsonData.

When the job has failed

{
  "status": "FAILED",
  "error_message": "{reason the presentation could not be generated}",
  "file_url": null
}

Poll every few seconds rather than in a tight loop — every 2 to 5 seconds is plenty. Always cap your polling with an overall timeout so a stuck job cannot block your application indefinitely.

Example request

Dummy PowerPoint template used in examples below:

# 1. Submit the job
curl --location --request POST 'https://gen.powerpointgeneratorapi.com/v2.0/generator/create-async' \
  -H 'Authorization: Bearer {add_your_token_here}' \
  -F 'files=@title_slide_template.pptx' \
  -F 'jsonData={"presentation":{"template":"title_slide_template.pptx","export_version":"Pptx2019","resultFileName":"quick_start_example","slides":[{"type":"slide","slide_index":0,"shapes":[{"name":"Title 1","content":"Your generated PowerPoint presentation"},{"name":"Subtitle 2","content":"Create, fill and manage PowerPoint documents through simple API requests."}]}]}}'

# {"job_id":"3f9c1a72-58d4-4f0e-9a7b-2c6d0b1e84af","status":"QUEUED"}

# 2. Poll the status until it reports SUCCEEDED
curl --location 'https://gen.powerpointgeneratorapi.com/v2.0/jobs/3f9c1a72-58d4-4f0e-9a7b-2c6d0b1e84af/status' \
  -H 'Authorization: Bearer {add_your_token_here}'

# {"status":"SUCCEEDED","error_message":null,"file_url":"https://pptx-gen-async.s3.eu-west-1.amazonaws.com/..."}

# 3. Download the finished presentation from the file_url returned in step 2.
#    It is a pre-signed link, so do not send the Authorization header.
curl --location '{file_url_from_step_2}' --output generated.pptx
import json
import time
import requests

TEMPLATE_PATH = './title_slide_template.pptx'   # where the file lives on disk
TEMPLATE_NAME = 'title_slide_template.pptx'     # upload name, same as jsonData "template"
API_TOKEN = 'eyJ...'                            # your bearer token

ASYNC_URL = 'https://gen.powerpointgeneratorapi.com/v2.0/generator/create-async'
STATUS_URL = 'https://gen.powerpointgeneratorapi.com/v2.0/jobs/{jobId}/status'
HEADERS = {'Authorization': f'Bearer {API_TOKEN}'}

payload = {
    'jsonData': json.dumps({
        "presentation": {
            "template": TEMPLATE_NAME,
            "export_version": "Pptx2019",
            "resultFileName": "quick_start_example",
            "slides": [
                {
                    "type": "slide",
                    "slide_index": 0,
                    "shapes": [
                        {"name": "Title 1", "content": "Your generated PowerPoint presentation"},
                        {"name": "Subtitle 2", "content": "Create, fill and manage PowerPoint documents through simple API requests."},
                    ],
                }
            ],
        }
    })
}


def submit_async_job():
    """Submit the job and return its job ID."""
    with open(TEMPLATE_PATH, 'rb') as f:
        files = [
            ('files', (TEMPLATE_NAME, f,
                       'application/vnd.openxmlformats-officedocument.presentationml.presentation'))
        ]
        response = requests.post(
            ASYNC_URL,
            data=payload,
            files=files,
            headers=HEADERS,
            timeout=500,
        )

    # A successful submission is returned as either 200 or 202
    if response.status_code not in (200, 202):
        print(f"Error submitting async job: {response.status_code} - {response.text}")
        return None

    result = response.json()
    print(f"Async job submitted. Job ID: {result['job_id']}, initial status: {result['status']}")
    return result['job_id']


def get_job_status(job_id):
    """Retrieve the current status of an async job."""
    response = requests.get(
        STATUS_URL.format(jobId=job_id),
        headers=HEADERS,
        timeout=30,
    )
    if response.status_code != 200:
        print(f"Error fetching job status: {response.status_code} - {response.text}")
        return None
    return response.json()


def wait_for_job(job_id, poll_seconds=5, timeout_seconds=1800):
    """Poll until the job finishes, or give up after timeout_seconds."""
    deadline = time.time() + timeout_seconds

    while time.time() < deadline:
        job = get_job_status(job_id)
        if job is None:
            return None

        status = job.get("status")
        print(f"Job {job_id}: {status}")

        if status == "SUCCEEDED":
            return job
        if status == "FAILED":
            print(f"Generation failed: {job.get('error_message')}")
            return None

        time.sleep(poll_seconds)

    print(f"Timed out after {timeout_seconds}s waiting for job {job_id}")
    return None


job_id = submit_async_job()

if job_id:
    job = wait_for_job(job_id)
    if job:
        # file_url is pre-signed - do not send the Authorization header.
        # Stream the response so large presentations are not held in memory.
        with requests.get(job["file_url"], stream=True, timeout=360) as download:
            download.raise_for_status()
            with open("./generated.pptx", "wb") as out:
                for chunk in download.iter_content(chunk_size=8192):
                    out.write(chunk)
        print("saved generated.pptx")
1

Select the Authorization tab, enter your Token.

2

Select the Body tab, select form-data, add the two key-value parameters below:

KEY
VALUE

files

upload/ attach your .pptx file

jsonData

copy and paste the data from your .json payload

3

POST to https://gen.powerpointgeneratorapi.com/v2.0/generator/create-async and copy the job_id from the response.

4

Open a new request, GET https://gen.powerpointgeneratorapi.com/v2.0/jobs/{jobId}/status with the same Authorization token, and hit Send every few seconds until status is SUCCEEDED.

5

Open a third request, GET the file_url from the status response with no Authorization header, then click the down arrow next to Send and select Send and Download to save the output as .pptx.

Last updated