Getting Started with the Prezent API
The Prezent Platform API exposes Prezent's AutoGenerator, Template Converter, Audiences, Themes, and File-upload services behind a single uniform JSON HTTP API.
This page walks you through the minimum you need to make a successful first call: the base URL, how to authenticate, what every response looks like, and how to drive long-running operations.
Looking for the full interactive API reference? Open the API Reference page or download the raw OpenAPI YAML.
Overview
- All endpoints accept and return
application/json. - Errors use one uniform envelope everywhere; success shapes vary per endpoint (see Response envelopes).
- Long-running endpoints return a
callback_id. AutoGenerator delivers the result over a stream; Template Converter is polled (see Async operations). - Authentication is Bearer-token based:
Authorization: Bearer <api_key>. - Identifiers in new endpoints and new fields use snake_case (for example
callback_id).
Base URL
| Environment | Host |
|---|---|
| Production (canonical) | https://api.prezent.ai |
| UAT | https://uatstage-api.myprezent.com |
| Development | https://devstage-api.myprezent.com |
All examples in this documentation use the canonical production host.
Authentication
The Prezent API uses API key (Bearer) authentication. Include your API key
on every request in the Authorization header:
Authorization: Bearer YOUR_API_KEY
- API keys are issued by your Customer Success Manager. Self-service key generation is not currently supported.
- Keys may have an
expiry_dateand astatus. An expired key returns401 EXPIRED_API_KEY. - Keys are scoped to specific endpoint paths. Calling an endpoint outside
your key's scope returns
404 ENDPOINT_NOT_FOUND. - API keys are masked after generation. Download and store your key securely; you will not be able to view it again.
For the full security model across every surface (Bearer vs. OAuth, key scoping, transport security, and webhook payload integrity), see Authentication & Security.
Making your first request
Verify your key is working with a simple call to the AutoGenerator service.
- cURL
- Node.js
- Python
- Go
- Java
curl -X POST https://api.prezent.ai/api/v2/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Generate a presentation on AI trends",
"template_id": "your-template-id"
}'
const axios = require('axios');
const startGeneration = async () => {
const { data } = await axios.post(
'https://api.prezent.ai/api/v2/generate',
{
prompt: 'Generate a presentation on AI trends',
template_id: 'your-template-id'
},
{
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
}
}
);
console.log(data);
// { message: "...", resData: { callback_id: "...", token: "..." }, error: null }
return data.resData.callback_id;
};
startGeneration();
import requests
url = "https://api.prezent.ai/api/v2/generate"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
}
payload = {
"prompt": "Generate a presentation on AI trends",
"template_id": "your-template-id",
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
body = response.json()
# {"message": "...", "resData": {"callback_id": "..."}, "error": null}
callback_id = body["resData"]["callback_id"]
print(callback_id)
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]string{
"prompt": "Generate a presentation on AI trends",
"template_id": "your-template-id",
})
req, _ := http.NewRequest("POST",
"https://api.prezent.ai/api/v2/generate", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var out map[string]any
json.NewDecoder(resp.Body).Decode(&out)
fmt.Println(out) // { message: "...", resData: { callback_id: "..." }, error: null }
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class StartGeneration {
public static void main(String[] args) throws Exception {
String body = "{\"prompt\":\"Generate a presentation on AI trends\","
+ "\"template_id\":\"your-template-id\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.prezent.ai/api/v2/generate"))
.header("Authorization", "Bearer YOUR_API_KEY")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// { "message": "...", "resData": { "callback_id": "..." }, "error": null }
}
}
Response envelopes
Errors are uniform across every endpoint. Success shapes are not — each endpoint documents its own, so read the response schema for the endpoint you are calling rather than assuming a shared shape.
Success shapes
Most endpoints use the canonical envelope:
{
"success": true,
"data": {
"...endpoint-specific payload..."
}
}
The notable exceptions on the AutoGenerator surface:
| Endpoint | Shape |
|---|---|
POST /api/v2/generate | { message, resData, error } — payload under resData |
POST /api/v2/autogenerator/edit | { message, resData, error } |
POST /api/v2/autogenerator/download | flat top-level fields |
GET /api/v2/autogenerator/languages | { status, message, data } |
The Template Converter has its own exceptions — see the Template Converter API.
Handlers may emit additional keys alongside the documented ones for backwards compatibility. These are not part of the contract; do not depend on undocumented keys.
Error envelope
{
"success": false,
"data": null,
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "The requested resource does not exist.",
"details": {
"callback_id": "abc-123"
}
}
}
successis alwaysfalseon an error response.datais alwaysnullon an error response.error.codeis a stable string identifier drawn from the error catalog. Codes never change meaning or HTTP status once published.error.messageis a human-readable English description.error.detailsis optional and may carry structured information (validation failures, downstream-service info, etc.).
The same envelope is returned by both in-handler errors and
gateway-level errors (UNAUTHORIZED, TOO_MANY_REQUESTS, etc.).
Status codes
| Status | Meaning |
|---|---|
200 OK | The call succeeded. |
202 Accepted | The request was accepted for asynchronous processing. |
400 Bad Request | Request shape or input is invalid. |
401 Unauthorized | Missing, invalid, or expired API key. |
403 Forbidden | Caller is authenticated but not allowed to perform this operation. |
404 Not Found | Endpoint or resource not found, or key is not scoped to this path. |
405 Method Not Allowed | HTTP method not supported on this path. |
415 Unsupported Media Type | File extension or MIME type rejected. |
422 Unprocessable Entity | Semantically invalid request body. |
429 Too Many Requests | Rate or usage limit exceeded; see Rate Limits. |
500 Internal Server Error | Unexpected server error. |
502 Bad Gateway | A downstream service returned an error. |
503 Service Unavailable | Service temporarily unavailable. |
504 Gateway Timeout | Upstream timeout. |
Error catalog
See the full list of stable error codes (per HTTP status) in the canonical Error Reference.
Rate limits
Three independent limits apply, each returning 429 with the standard
error envelope. Default values (all configurable per company):
| Tier | Default | error.code |
|---|---|---|
| Gateway throttle (per key) | 10 req/s, 5 burst, 1,000 req/day | TOO_MANY_REQUESTS |
| Per-company × category, 60-second sliding window | configured per company | RATE_LIMIT_EXCEEDED |
| Annual usage quota | 50,000 slide generations/yr · 1,000,000 downloads/yr | USAGE_LIMIT_EXCEEDED |
Read X-RateLimit-Remaining to pace yourself and honour Retry-After
on a 429. The full table, response-header reference, and a
copy-pasteable backoff loop are on the dedicated
Rate Limits page.
Async operations
Long-running endpoints return a callback_id immediately and do the work
in the background. How you learn it finished differs by service:
| Service | Mechanism |
|---|---|
| AutoGenerator | Open a stream and read events |
| Template Converter | Poll a status endpoint |
AutoGenerator — streaming
There is no status endpoint. POST /api/v2/generate returns a
callback_id at resData.callback_id; exchange it for a stream URL and
read the events:
# 1. Start the generation
curl -s -X POST https://api.prezent.ai/api/v2/generate \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"Generate a presentation on AI trends","template_id":"tmpl-1"}'
# { "message": "...", "resData": { "callback_id": "cb_123" }, "error": null }
# 2. Mint a stream URL for that callback_id
curl -s -X POST https://api.prezent.ai/api/v2/streams/sessions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"callback_id":"cb_123"}'
# { "success": true, "data": { "stream_url": "https://stream-api-...", ... } }
# 3. Read it. -N disables buffering; the token is in the URL, so no auth header.
curl -N "$STREAM_URL"
# event: status
# data: {"status":"inprogress","message":"Analyzing the key elements","callback_id":"cb_123"}
# …
# event: done
# data: {"status":"success","message":"Your presentation is ready","callback_id":"cb_123","download_url":"..."}
Every event has the same shape, so one parser handles the stream: read
status until it is no longer inprogress, and show message to your
user as-is. Full details in Streaming (SSE) and the
AI Builder API.
POST /api/v2/autogenerator/download returns a stream_url directly,
skipping step 2.
Template Converter — polling
The Template Converter is unchanged in 2.0 and still polls.
POST /api/v1/template-converter/start returns the id at top-level
callbackId; poll
GET /api/v1/template-converter/status/{callbackId}.
The response is 200 whenever the job is found — inspect the status
field in the body to distinguish in-progress from completed and failed.
Poll every 2–5 seconds with exponential backoff.
Next steps
- Browse every endpoint in the API Reference.
- Building with an AI agent? Skip directly to Agents & MCP — Claude, Cursor, Cline, Continue, and Zed can call Prezent as MCP tools without any HTTP plumbing.
- Read the Developer Guide for rate limits, error codes, and best practices.
- Dive into the per-API guides:
- Auto Generate
- Template Converter
- Audiences
- Themes
- File Upload
- File Access
- Health
- SCIM — User Management (separate RFC 7644 contract)