Template Converter API
The Template Converter API applies a target brand template to an
uploaded deck. The pipeline is asynchronous: kick off a job with
POST /api/v1/template-converter/start, then poll
GET /api/v1/template-converter/status/{callbackId} until the workflow
reaches a terminal state.
Full schemas, request/response examples, and per-field documentation live in the interactive API Reference.
Skip the polling loop. If you can expose an HTTPS endpoint, subscribe to
template_conversion.completed/template_conversion.failedvia the Webhooks API and receive signed completion callbacks instead of polling for status.
Authentication
All endpoints require a Bearer token:
Authorization: Bearer YOUR_API_KEY
See Getting Started → Authentication for details.
Response envelope
Errors use the canonical envelope:
{ "success": false, "data": null, "error": { "code": "...", "message": "..." } }
Success responses in this family are not uniformly enveloped. Several
endpoints return their fields at the top level rather than under data,
and some use camelCase keys. Each endpoint below documents its own
success shape — read it rather than assuming data.
Endpoint summary
| Method | Path | Description | Sync/Async |
|---|---|---|---|
POST | /api/v1/template-converter/start | Create a template-conversion job | Async |
GET | /api/v1/template-converter/status/{callbackId} | Poll a conversion job | Sync |
GET | /api/v1/templates?feature=template_converter | List templates available to Template Converter | Sync |
POST | /api/v1/template-converter/preprocess | Upload a PPTX in chunks | Sync |
POST | /api/v1/template-converter/finalprocess | Finalise a chunked PPTX upload | Sync |
GET | /api/v1/template-converter/{callbackId}/review-suggestions | Get editorial review suggestions | Sync |
PATCH | /api/v1/template-converter/{callbackId}/review-suggestions | Apply a colour change from review suggestions | Async |
POST | /api/v1/template-converter/{callbackId}/template-change | Re-convert to a different template | Async |
GET | /api/v1/template-converter/download/{callbackId} | Get a signed download URL | Sync |
PUT | /api/v1/template-converter/reaction-feedback | Record like / feedback | Sync |
GET | /api/v1/template-converter/work-area-options | Get work-area options for a slide | Sync |
POST | /api/v1/template-converter/adjust-work-area | Apply a work-area adjustment | Sync |
GET | /api/v1/template-converter/layouts | Get layout options for a slide | Sync |
POST | /api/v1/template-converter/update-layout | Change the layout of one or more slides | Async |
POST | /api/v1/template-converter/modify-format | Apply title/body formatting changes | Async |
GET | /api/v1/template-converter/modify-format-settings | Get current modify-format settings for every slide | Sync |
All endpoints are in the template_converter rate-limit category. The
start and download operations also count against per-key annual usage
quotas (negotiated per customer — contact CS for your tier). See
Developer Guide → Usage quotas and rate limits.
POST /api/v1/template-converter/start — Create a conversion
Kicks off a template-conversion pipeline. Returns a callback_id to
poll. Counts against the TC_START usage limit.
Pass either fileId (an id returned by a previous upload) or
inputDeck (an inline reference to the input deck). If both are sent,
fileId wins.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
fileId | string | conditional | Id of a previously uploaded input deck. Deck details are resolved server-side. |
inputDeck | object | conditional | Inline reference to the input deck. Requires numOfPages (integer), s3Bucket (string), s3Prefix (string), and sizeKb (number); presentationName is optional. |
templateName | string | yes | Code of the target brand template. Must be one your company is authorised to use. |
includeImageWithoutData | boolean | no | Carry over images that have no associated data. Defaults to false. |
includeImageWithData | boolean | no | Carry over images that have associated data. Defaults to false. |
includeIcons | boolean | no | Carry over icons. Defaults to false. |
includeSpecialColor | boolean | no | Preserve special color treatments. Defaults to false. |
color_preference | string | no | standard or advanced. Defaults to standard. Also accepted as colorPreference. |
content_formatting_preference | string | no | standard or advanced. Also accepted as contentFormattingPreference. |
modifyFormat | string | no | source or target. Also accepted as modify_format. |
settings | object | no | Per-conversion settings — see below. |
Every optional setting falls back to the defaults configured for your API key, then to the documented default.
settings key | Allowed values | Default |
|---|---|---|
ai_mode | standard, thinking | standard |
work_area_option | no-adjust, auto-adjust, scale-to-fit, auto-adjust-la | no-adjust |
modifyFormat | source, target | — |
color_preference | standard, advanced | standard |
Example
- cURL
- Python
- Node.js
curl -X POST https://api.prezent.ai/api/v1/template-converter/start \
-H "Authorization: Bearer $PREZENT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fileId": "file_abc123",
"templateName": "prezent_corporate_2022",
"includeImageWithData": true,
"settings": {
"ai_mode": "standard",
"color_preference": "standard"
}
}'
import os
import requests
url = "https://api.prezent.ai/api/v1/template-converter/start"
headers = {
"Authorization": f"Bearer {os.environ['PREZENT_API_KEY']}",
"Content-Type": "application/json",
}
payload = {
"fileId": "file_abc123",
"templateName": "prezent_corporate_2022",
"includeImageWithData": True,
"settings": {
"ai_mode": "standard",
"color_preference": "standard",
},
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
print(response.json())
const axios = require('axios');
const createConversion = async () => {
const { data } = await axios.post(
'https://api.prezent.ai/api/v1/template-converter/start',
{
fileId: 'file_abc123',
templateName: 'prezent_corporate_2022',
includeImageWithData: true,
settings: {
ai_mode: 'standard',
color_preference: 'standard'
}
},
{
headers: {
Authorization: `Bearer ${process.env.PREZENT_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
console.log(data);
return data.callbackId;
};
createConversion();
Success response (200)
Fields are returned at the top level, in camelCase:
{
"callbackId": "cb_tc_xyz",
"status": "processing",
"presentationName": "Q3 review.pptx",
"token": "tok_one_time_xyz"
}
GET /api/v1/template-converter/status/{callbackId} — Poll a job
The polling endpoint for the Template Converter family. It returns
HTTP 200 whenever the job is found — inspect data.status to
determine whether the pipeline is still running, has completed, or has
failed. Do not branch on the HTTP status alone.
Polling after a successful conversion returns the same cached payload.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id (from POST /api/v1/template-converter/start). |
Example
- cURL
- Python
- Node.js
curl -i "https://api.prezent.ai/api/v1/template-converter/status/cb_tc_xyz" \
-H "Authorization: Bearer $PREZENT_API_KEY"
import os
import requests
url = "https://api.prezent.ai/api/v1/template-converter/status/cb_tc_xyz"
headers = {
"Authorization": f"Bearer {os.environ['PREZENT_API_KEY']}",
}
response = requests.get(url, headers=headers)
# Strict status mapping: 200 = done, 202 = in progress, 4xx/5xx = failure
print(response.status_code)
print(response.json())
const axios = require('axios');
const pollStatus = async () => {
const response = await axios.get(
'https://api.prezent.ai/api/v1/template-converter/status/cb_tc_xyz',
{
headers: {
Authorization: `Bearer ${process.env.PREZENT_API_KEY}`
},
// Inspect 202 (in progress) without throwing
validateStatus: (status) => status < 500
}
);
// Strict status mapping: 200 = done, 202 = in progress, 4xx/5xx = failure
console.log(response.status);
console.log(response.data);
};
pollStatus();
Success response (200)
{
"success": true,
"data": {
"callback_id": "cb_tc_xyz",
"status": "success",
"presentation_name": "Q3 review (Corporate 2024).pptx",
"template_name": "Corporate 2024",
"outputs": { "...": "..." }
}
}
In-progress response (202)
{
"success": true,
"data": {
"callback_id": "cb_tc_xyz",
"status": "in_progress",
"presentation_name": "Q3 review.pptx",
"template_name": "Corporate 2024",
"progress": { "stage": "rendering", "percent": 67 }
}
}
Failure responses
On workflow failure the response is 4xx or 5xx with the standard
error envelope:
{
"success": false,
"data": null,
"error": {
"code": "EXTERNAL_SERVICE_ERROR",
"message": "Conversion failed at the layout-resolution stage.",
"details": { "stage": "layout" }
}
}
| HTTP | Typical codes |
|---|---|
400 | MISSING_CALLBACK_ID, INVALID_INPUT. |
401 | UNAUTHORIZED, INVALID_API_KEY, EXPIRED_API_KEY. |
404 | RESOURCE_NOT_FOUND (unknown callback_id). |
422 | UNPROCESSABLE_ENTITY (job was malformed at start). |
429 | RATE_LIMIT_EXCEEDED, USAGE_LIMIT_EXCEEDED. |
500 | INTERNAL_SERVER_ERROR. |
502 | EXTERNAL_SERVICE_ERROR (downstream conversion pipeline error). |
503 | SERVICE_UNAVAILABLE. |
504 | GATEWAY_TIMEOUT. |
GET /api/v1/templates?feature=template_converter — List templates
Returns themes/templates available to Template Converter. This single
endpoint replaces the legacy /api/v1/autogenerator/templates and
/api/v1/template-converter/templates paths — pass feature to
scope results.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
feature | string (auto_generator / template_converter) | no | Filter to templates enabled for a specific feature. |
name | string | no | Case-insensitive name filter. |
sort | string | no | Sort expression. |
source | string | no | Source filter. |
Success response (200)
{
"success": true,
"data": {
"items": [
{ "id": "tmpl_corp_2024", "name": "Corporate 2024", "code": "CORP24", "source": "brand" }
],
"next_cursor": null
}
}
Chunked upload — preprocess + finalprocess
For input decks too large to send in a single request, use the chunked-upload flow.
POST /api/v1/template-converter/preprocess
Accepts one chunk of a multi-chunk PPTX upload. See the shared schema
on the File Upload page (PreprocessFileRequest).
Chunks of the same upload are grouped by requestIdentifier. Only
.pptx files are accepted.
POST /api/v1/template-converter/finalprocess
Concludes the chunked upload. The finalised file must be a .pptx, no
larger than 200 MB, and no more than 100 pages.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
fileIdentifier | string | yes | Identifier shared across all chunks. Must match the requestIdentifier sent with each chunk. |
fileName | string | yes | Final filename. Must end in .pptx. |
Success response (200)
The envelope uses status and log rather than success, and the
data fields are camelCase:
{
"status": "success",
"log": "File uploaded successfully",
"data": {
"fileId": "file_abc123",
"s3Prefix": "uploads/co_xyz/file_abc123/",
"s3Bucket": "prezent-uploads",
"type": "s3",
"sizeKb": 18432,
"numOfPages": 42
}
}
data.fileId is what you pass to POST /api/v1/template-converter/start
as fileId.
Smart-edit endpoints
These endpoints let you refine an already-converted deck without re-running the full conversion from scratch.
GET /api/v1/template-converter/{callbackId}/review-suggestions
Returns the colour and special-colour suggestions produced for the converted deck. The conversion must have completed and produced compliance data.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. |
Success response (200)
{
"success": true,
"data": {
"callback_id": "cb_tc_xyz",
"presentation_name": "Q3 review (Corporate 2024).pptx",
"suggestions": [ { "..." : "..." } ]
}
}
PATCH /api/v1/template-converter/{callbackId}/review-suggestions
Applies a colour change to the converted deck. Kicks off a background
pipeline; the response carries a new callback_id to poll.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. |
Request body
Send at least one of colorSuggestions or specialColorSuggestions.
Whichever you send must carry status: "edited" and a values object
with both currentColor and newColor.
| Field | Type | Required | Description |
|---|---|---|---|
colorSuggestions | object | conditional | Colour replacement to apply. |
colorSuggestions.status | string | yes | Must be edited. |
colorSuggestions.values.currentColor | string | yes | The colour being replaced. |
colorSuggestions.values.newColor | string | yes | The replacement colour. |
specialColorSuggestions | object | conditional | Special-colour replacement, same shape as above. |
{
"colorSuggestions": {
"status": "edited",
"values": {
"currentColor": "#1F4E79",
"newColor": "#21A6F9"
}
}
}
Success response (200)
{ "status": "processing", "callbackId": "cb_tc_xyz_v2", "presentationName": "Q3 review.pptx" }
POST /api/v1/template-converter/{callbackId}/template-change
Re-runs the conversion pipeline for an already-converted deck against
a different templateName. Returns a new callback_id to poll.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
templateName | string | yes | Code of the new target brand template. Must be one your company is authorised to use. |
{
"templateName": "prezent_corporate_2022"
}
Success response (200)
{ "status": "processing", "callbackId": "cb_tc_xyz_v3", "presentationName": "Q3 review.pptx" }
GET /api/v1/template-converter/work-area-options
Returns available work-area adjustment options for a slide.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. Must correspond to a live conversion session. |
slideIndex | integer ≥ 0 | yes | Zero-based slide index. |
Success response (200)
{
"success": true,
"data": {
"callback_id": "cb_tc_xyz",
"work_area_adjustments": [ { "..." : "..." } ]
}
}
POST /api/v1/template-converter/adjust-work-area
Applies a selected work-area adjustment to a slide. All parameters go in the request body.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. Must correspond to a live conversion session. |
slideIndex | integer ≥ 0 | yes | Zero-based slide index. |
selection | string | yes | The work-area option to apply. Must be one of the options currently available for this slide — fetch them first via GET /api/v1/template-converter/work-area-options. |
{
"callbackId": "cb_tc_xyz",
"slideIndex": 0,
"selection": "<value from work-area-options>"
}
Success response (200)
{ "success": true, "data": { "message": "Adjustment applied." } }
GET /api/v1/template-converter/layouts
Returns the layout options available for a slide.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. Must correspond to a live conversion session. |
slideIndex | integer ≥ 0 | yes | Zero-based slide index. |
Success response (200)
{
"success": true,
"data": {
"callback_id": "cb_tc_xyz",
"status": "success",
"layouts": {
"target_template_layouts": [ { "..." : "..." } ],
"input_deck_layouts": [ { "..." : "..." } ]
}
}
}
POST /api/v1/template-converter/update-layout
Updates the layout of one or more slides and re-renders the affected
portion of the deck. Returns a new callback_id to poll. All parameters
go in the request body.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. Must correspond to a live conversion session. |
slideIndex | array of integer | yes | Zero-based indices of the slides to update. Must be an array with at least one element, even for a single slide. |
layoutId | string | yes | Target layout id, taken from GET /api/v1/template-converter/layouts. |
source | string | yes | Which layout collection layoutId belongs to — targetTemplateLayouts or inputDeckLayouts. |
{
"callbackId": "cb_tc_xyz",
"slideIndex": [0],
"layoutId": "layout_abc123",
"source": "targetTemplateLayouts"
}
Success response (200)
{ "status": "processing", "callbackId": "cb_tc_xyz_v4" }
POST /api/v1/template-converter/modify-format
Applies a batch of title/body formatting changes and re-renders the
affected slides. Returns a new callback_id to poll. All parameters go
in the request body, and the conversion must have completed first.
Request body
Note the mixed casing: callbackId and slideIndex are camelCase, while
selection_type, overall_settings_selected, and
modify_format_config are snake_case.
| Field | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. Must correspond to a live, completed conversion. |
slideIndex | array of integer | yes | Zero-based indices of the slides to restyle. Each value must be within the deck's slide count. |
selection_type | string | no | How the selection was made — single, all, custom, apply to slides after the current slide, or apply to slides before the current slide. Derived automatically when omitted. |
overall_settings_selected | boolean | no | When true, deck-level settings are applied and modify_format_config is not required. Defaults to false. |
modify_format_config | array of object | conditional | Per-slide formatting modifications. Required unless overall_settings_selected is true. |
modify_format_config must be the same length as slideIndex —
entry i applies to slide slideIndex[i]. Each entry must contain
either title or body, never both.
Each section object requires all seven of font_height,
font_case, font_bold, font_italic, font_underline,
vertical_alignment, and horizontal_alignment. Each of those is an
object with option_type and value:
option_type: "target"— inherit the target template's value.valuemust be an empty string.option_type: "custom"— override it, withvalueone of:
| Property | Allowed custom values |
|---|---|
font_height | 8, 9, 10, 10.5, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 44, 48, 54, 60, 72, 96 |
font_case | lowerCase, upperCase, capitaliseCase, sentenceCase |
vertical_alignment | top, middle, bottom |
horizontal_alignment | left, center, right, justified |
{
"callbackId": "cb_tc_xyz",
"slideIndex": [0],
"modify_format_config": [
{
"title": {
"font_height": { "option_type": "custom", "value": 24 },
"font_case": { "option_type": "custom", "value": "upperCase" },
"font_bold": { "option_type": "target", "value": "" },
"font_italic": { "option_type": "target", "value": "" },
"font_underline": { "option_type": "target", "value": "" },
"vertical_alignment": { "option_type": "custom", "value": "middle" },
"horizontal_alignment": { "option_type": "custom", "value": "center" }
}
}
]
}
Success response (200)
{ "status": "processing", "callbackId": "cb_tc_xyz_v5" }
GET /api/v1/template-converter/modify-format-settings
Returns the current title/body formatting settings for every slide of
a converted deck. Use these as the starting point for a
POST /api/v1/template-converter/modify-format request. The conversion
must have completed.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. Must correspond to a completed conversion. |
Success response (200)
Fields are returned at the top level, not nested under data:
{
"callbackId": "cb_tc_xyz",
"modify_format_settings": [ { "..." : "..." } ]
}
GET /api/v1/template-converter/download/{callbackId} — Download
Returns a signed download URL for the converted deck. Counts against
the TC_DOWNLOAD usage limit.
The conversion must have reached completed first — poll
GET /api/v1/template-converter/status/{callbackId} before calling this,
otherwise the request is rejected with the current status.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
callbackId | string | yes | Conversion job id. |
Success response (200)
{
"success": true,
"data": {
"download_url": "https://...signed-url...",
"file_name": "Q3 review (Corporate 2024).pptx",
"message": "Ready to download."
}
}
PUT /api/v1/template-converter/reaction-feedback — Like / feedback
Records a like or qualitative feedback against a converted deck. This
endpoint accepts PUT only — a POST returns METHOD_NOT_ALLOWED.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
callback_id | string | yes | Converted-deck callback id. Must correspond to a live conversion session. |
type | string | yes | liked or feedback. |
value | boolean or string | yes | Boolean when type=liked; string when type=feedback. An empty string is rejected. |
{
"callback_id": "cb_tc_xyz",
"type": "liked",
"value": true
}
Success response (200)
{
"success": true,
"data": {
"callback_id": "cb_tc_xyz",
"type": "liked",
"message": "Reaction recorded.",
"warnings": []
}
}
Errors
All endpoints on this page return the standard error envelope. Common codes:
400—MISSING_CALLBACK_ID,MISSING_TEMPLATE_ID,INVALID_INPUT,INVALID_PAYLOAD.401—INVALID_API_KEY,EXPIRED_API_KEY,UNAUTHORIZED.404—ENDPOINT_NOT_FOUND,RESOURCE_NOT_FOUND.415—UNSUPPORTED_FILE_TYPE(uploads / chunking only).429—RATE_LIMIT_EXCEEDED,USAGE_LIMIT_EXCEEDED.500/502/503/504— standard server-side codes.
See the full catalog in Developer Guide → Error codes.