Developer Guide
This guide collects the cross-cutting topics that apply to every Prezent Platform API endpoint — rate limits, the error catalog, async operations, and the response headers you should expect.
For the full interactive endpoint reference, see the API Reference. For first-call walkthroughs, see Getting Started.
What you'll find here
- Overview of Prezent APIs
- Authentication recap
- Response envelopes
- Rate limits
- Error codes
- Async operations
- Idempotency
- Pagination
- Best practices
- Where to go next
Overview of Prezent APIs
| API | Description |
|---|---|
| AutoGenerator | Generate Prezent-quality decks from natural-language prompts, files, and assets. Async + sub-endpoints for download, regenerate, image search, and slide actions. |
| Template Converter | Apply a target brand template to an uploaded deck. Async with the recommended v2 status endpoint, plus smart-edit endpoints (work-area, layout, modify-format, review suggestions). |
| Audiences | List and search audience profiles configured for your company. |
| Themes | List the presentation themes (brand templates) configured for your company. |
| File Upload | Upload (single + chunked) and validate supporting files before AutoGenerator / Template Converter jobs. |
| File Access | Mint short-lived access tokens for your stored files. |
| Health | Liveness and component health-check endpoints. |
| SCIM — User Management | RFC 7644 (SCIM 2.0) user provisioning. Documented separately. |
Authentication recap
All endpoints (except SCIM, which is documented separately) use a single Bearer token:
Authorization: Bearer YOUR_API_KEY
See Getting Started → Authentication for the full details, or Authentication & Security for the complete security model (key scoping, transport security, and webhook payload integrity across every surface).
Response envelopes
Every documented endpoint returns either the success envelope or the error envelope.
Success envelope
{
"success": true,
"data": { "...endpoint-specific payload..." }
}
Error envelope
{
"success": false,
"data": null,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Per-company per-category rate limit hit.",
"details": { "category": "autogenerator" }
}
}
Handlers may emit additional legacy keys alongside success, data, and
error. These are not part of the contract and may change without
notice.
Usage quotas and rate limits
For a single self-contained reference — all three tiers, the
429error codes, the response-header table, and a copy-pasteable backoff retry loop — see the dedicated Rate Limits page.
The Prezent API enforces three independent kinds of limits, applied in this order:
- Gateway throttle — a per-API-key request-rate + daily request cap enforced at the AWS API Gateway edge. Applies to every endpoint regardless of category.
- Per-minute rate limits — application-level, per-company ×
per-category throttling. Returns
HTTP 429withX-RateLimit-*headers when configured and exceeded. - Annual usage quotas — application-level, per-key caps on
specific billable operations (slide generation, presentation
downloads). Returns
HTTP 429witherror.code: "USAGE_LIMIT_EXCEEDED".
For any given request, the most restrictive of the three binds first. All three are configurable per company — contact your CSM to adjust.
Gateway throttle (default, applies to every key)
| Setting | Default |
|---|---|
| Steady request rate | 10 requests / second per API key |
| Burst capacity | 5 requests |
| Daily request quota | 1,000 requests / day per API key, across all endpoints |
Custom usage plans can raise these caps per customer. When you exceed
the throttle, API Gateway returns HTTP 429 with the canonical error
envelope and a Retry-After header.
Annual usage quotas
Default quotas for new customers (configurable per company):
| Operation | Default quota (per year) | Counted by |
|---|---|---|
Slide generation — POST /api/v1/autogenerator, POST /api/v1/autogenerator/regenerate | 50,000 requests / year | successful slides generated |
Presentation download — POST /api/v1/autogenerator/download | 1,000,000 requests / year | successful downloads |
Template-Converter start — POST /api/v1/template-converter/start | Negotiated per customer | successful TC starts |
Template-Converter download — GET /api/v1/template-converter/download/{callback_id} | Negotiated per customer | successful TC downloads |
Quotas are tracked on the API key. When a key exceeds its quota the API
returns HTTP 429 with error.code: "USAGE_LIMIT_EXCEEDED". All other
endpoints (audiences, themes, upload, file-access, SCIM, status polls,
etc.) do not consume any annual quota.
Per-minute rate limits
Per-minute limits are enforced per company × API category, per 60-second sliding window. Three categories exist in production today:
| Category | Endpoints in this category | Default limit |
|---|---|---|
auto_generator | All /api/v1/autogenerator/*, plus /api/v1/audiences, /api/v1/audiences/search, /api/v1/themes, /api/v1/upload, /api/v1/preprocess, /api/v1/validate, /api/v1/file-access | Configured per company — contact CS |
template_converter | All /api/v1/template-converter/* and /api/v2/template-converter/* | Configured per company — contact CS |
scim | All /api/v1/scim/* | Configured per company — contact CS |
Endpoints not classified under one of the above (health checks) are not throttled by the per-minute limiter today — only the gateway throttle and annual quotas apply to them.
Per-minute limits are not enforced for any company until a row exists in
the api_rate_limits configuration for that company + category. In
practice the gateway throttle (1,000/day) is the most restrictive
default and will bind first for most workloads.
429 response shape
There are two distinct HTTP 429 surfaces in the stack — both use the
canonical error envelope, but they emit slightly different headers:
Gateway throttle 429 — emitted by AWS API Gateway when the
per-key 10 req/s, 5 burst, or 1,000 req/day cap is exceeded:
- Header:
Retry-After: 60(default; clients should back off ~60s) - Body: canonical error envelope;
error.codewill be"TOO_MANY_REQUESTS"
Application per-minute 429 — emitted by the Lambda's per-category rate limiter when configured per-company limits are exceeded:
| Header | Description |
|---|---|
X-RateLimit-Limit | Configured requests-per-window for the category. |
X-RateLimit-Remaining | Approximate requests remaining in the current window. |
X-RateLimit-Reset | Unix timestamp (seconds) when the window resets. |
Retry-After | Seconds the client should wait before retrying. |
Response body
{
"success": false,
"data": null,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded for this category. Try again later.",
"details": {
"category": "autogenerator",
"retry_after_seconds": 12
}
}
}
error.code will be one of TOO_MANY_REQUESTS (gateway),
RATE_LIMIT_EXCEEDED, USAGE_LIMIT_EXCEEDED, THROTTLED (image
search/replace), or MAX_RETRIES_EXCEEDED.
Error codes
error.code is a stable string from a fixed catalog — a code never changes
its meaning or HTTP status once published. Branch your error handling on
error.code (and the HTTP status), not on error.message.
The full catalog, grouped by HTTP status, lives on the dedicated Error Reference page. A few of the most common codes:
| HTTP | Code | Meaning |
|---|---|---|
400 | MISSING_REQUIRED_FIELD | A required field is absent. |
401 | INVALID_API_KEY | API key not found or not authorized. |
403 | FORBIDDEN | Access to the resource is forbidden. |
404 | RESOURCE_NOT_FOUND | The requested resource does not exist. |
409 | IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_BODY | Same Idempotency-Key, different body. |
422 | INVALID_INPUT | Input failed validation. |
429 | RATE_LIMIT_EXCEEDED | Per-company per-category rate limit hit. |
500 | INTERNAL_SERVER_ERROR | Unexpected server error. |
See the Error Reference for the complete list — including the webhook, streaming, and idempotency codes — and the uniform error envelope.
Async operations
Several Prezent endpoints kick off background work. The pattern is the same across families:
POSTto the entry endpoint. The response carries adata.callback_id.- Poll the corresponding status endpoint.
- Branch on a terminal state (
success/failed) or, for the v2 Template Converter status endpoint, on the HTTP status itself.
v1 status endpoints (legacy semantics)
v1 status endpoints always return HTTP 200 (even when the underlying
workflow fails). To distinguish success from failure, inspect
data.status — typically one of in_progress, success, failed.
v1 paths remain live for backwards compatibility.
v2 status endpoints — strict HTTP-status mapping (recommended)
v2 status endpoints map workflow state onto HTTP status:
200only when the workflow has completed successfully.202while the workflow is still in progress.4xx/5xxon workflow failure, with the standard error envelope.
The first v2 status endpoint is for the Template Converter family:
GET /api/v2/template-converter/status/{callback_id}
Agents should prefer this endpoint over the v1 polling endpoint because it allows branching on HTTP status alone.
Polling cadence
Recommend 2–5 seconds initial interval with exponential backoff up to ~30 seconds. Most jobs terminate within 60–120 seconds; some Template Converter and AutoGenerator jobs run longer.
Idempotency
Every resource-creating write (POST/PUT/PATCH) accepts an
optional Idempotency-Key request header so you can safely retry a
request after a network error without creating a duplicate job.
- Send a unique key (a UUID is ideal) per logical operation:
Idempotency-Key: 1d8e…. - The first request is processed normally and the full response is cached for 24 hours.
- A retry with the same key and an identical body returns the
cached response verbatim, plus an
Idempotency-Replayed: trueresponse header — so the job is never created twice. - A retry with the same key but a different body returns
409 IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_BODY. Reuse a key only for true retries of the same request.
curl -X POST https://api.prezent.ai/api/v1/autogenerations \
-H "Authorization: Bearer $PREZENT_API_KEY" \
-H "Idempotency-Key: 8e6df756-18f6-4f16-8e12-7d7a5c5cb181" \
-H "Content-Type: application/json" \
-d '{"prompt": "A 5-slide deck on renewable energy"}'
Idempotency is best-effort and fail-open: if the cache is briefly unavailable, the request is processed as a normal (non-replayed) call.
Pagination
List endpoints support opt-in cursor pagination. It is fully
backward-compatible: when you send neither limit nor cursor, the
endpoint returns the complete list exactly as before.
limit— items per page,1–200(default50). Sending it turns pagination on.cursor— opaque token from the previous response'snext_cursor.next_cursor— present in the response body;nullon the last page.
# First page
curl "https://api.prezent.ai/api/v1/audiences?limit=50" \
-H "Authorization: Bearer $PREZENT_API_KEY"
# -> { "items": [...], "next_cursor": "eyJpZHgiOjQ5fQ==" }
# Next page
curl "https://api.prezent.ai/api/v1/audiences?limit=50&cursor=eyJpZHgiOjQ5fQ==" \
-H "Authorization: Bearer $PREZENT_API_KEY"
Pagination is available on the list endpoints: /api/v1/audiences,
/api/v1/themes, /api/v1/templates (and its
/api/v1/autogenerator/templates and
/api/v1/template-converter/templates aliases), and
/api/v1/webhook-subscriptions.
Best practices
- Keep your API keys secure. Do not commit them to source control or share them in screenshots.
- Use the right environment. Build and test against UAT
(
https://uatstage-api.myprezent.com) before promoting to production. - Respect rate limits. When you hit
429, honour theRetry-Afterheader. Use jittered exponential backoff for retries. - Poll with backoff. Do not poll status endpoints faster than every 2 seconds.
- Prefer v2 status endpoints for the Template Converter family — strict HTTP-status mapping is simpler to integrate against.
- Pin to documented fields. Handlers may emit additional legacy keys alongside the contract; do not depend on them.
Where to go next
| If you want to | Go to |
|---|---|
| Browse every endpoint interactively | API Reference |
| Set up authentication | Getting Started → Authentication |
| Generate your API key | API Keys |
| See API usage and quotas | API Usage |
| Get integration help | Help |
| Stay current on changes | Change Log |