Prezent Upload API
Validate, preprocess, and upload supporting files (PowerPoint, PDF, images, etc.).
Validate, preprocess, and upload supporting files (PowerPoint, PDF, images, etc.).
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/prezent-upload-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: Prezent Platform Upload API
version: 1.0.0
summary: Agent-ready REST API for Prezent's content-generation and template-conversion services.
description: "The Prezent Platform API exposes Prezent's AutoGenerator, Template Converter,\nAudiences, Themes, and File-upload services as a uniform JSON HTTP API.\n\nThis contract describes the **target agent-ready shape** of the API: every\ndocumented endpoint returns a uniform success envelope `{ \"success\": true,\n\"data\": { ... } }` or a uniform error envelope `{ \"success\": false,\n\"data\": null, \"error\": { \"code\": \"...\", \"message\": \"...\", \"details\": { ... } } }`.\nError codes are drawn from a stable catalog (see `ErrorCode`). The contract\nis additive: handlers may continue to emit legacy keys alongside the\ndocumented ones for backwards compatibility, so schemas explicitly allow\nadditional properties at the envelope and data levels.\n\nSeveral endpoints kick off long-running background work and return a\n`callback_id` that the client polls against a corresponding status\nendpoint. The canonical async polling endpoint for the Template Converter\nfamily is **`GET /api/v2/template-converter/status/{callback_id}`** which\nuses strict HTTP-status mapping (200 only on workflow success, 4xx/5xx on\nworkflow failure). The v1 polling endpoint at\n`/api/v1/template-converter/status/{callbackId}` (and its REST alias\n`GET /api/v1/template-conversions/{callback_id}`) continues to be served\nwith legacy semantics (HTTP 200 with `status` field) and is intentionally\nomitted from this documentation.\n\n**REST resource aliases (v1.1).** AutoGenerator and Template Converter\nendpoints are documented here under their REST-resource path names\n(`/api/v1/autogenerations`, `/api/v1/template-conversions`). The legacy\nRPC-style paths under `/api/v1/autogenerator/*` and\n`/api/v1/template-converter/*` continue to be served indefinitely; they\nreturn a `Deprecation: true` header pointing to the successor alias.\n\n**Conventions that apply to every endpoint** (full reference in the\ncompanion guides on this documentation site):\n\n- **Auth:** API key as a Bearer token — `Authorization: Bearer <key>`.\n Each key is scoped to an allow-list of endpoint paths; an out-of-scope\n call returns `404 ENDPOINT_NOT_FOUND`.\n- **Rate limits:** gateway throttle 10 req/s sustained, 5 burst,\n 1,000 req/day per key; per-company per-category 60-second sliding\n windows; annual quotas (50,000 slide generations/yr, 1,000,000\n downloads/yr). Limit breaches return `429` with `error.code`\n `TOO_MANY_REQUESTS` (gateway), `RATE_LIMIT_EXCEEDED` (per-category),\n or `USAGE_LIMIT_EXCEEDED` (annual).\n- **Errors:** every error uses the `{ success:false, data:null, error:{\n code, message, details } }` envelope with stable, documented `code`\n values.\n- **Idempotency & pagination:** mutating requests accept an\n `Idempotency-Key`; list endpoints accept opt-in `limit`/`cursor`\n paging.\n\n**Building with an AI agent?** Prezent ships a first-class Model Context\nProtocol (MCP) server. The hosted endpoint is\n`https://mcp.myprezent.com/mcp` (OAuth 2.1, works with Claude.ai Custom\nConnectors); a local stdio server is published on PyPI as\n`prezent-mcp-server` and plugs into Claude Desktop, Cursor, Cline,\nContinue, and Zed. The MCP tools wrap the same REST endpoints\ndescribed here.\n\n**Official SDKs.** Typed REST clients are published for Python and\nTypeScript (`prezent-sdk`) — generated from and versioned against this\nspec. For other languages, generate a client from this document.\n\n**Out of scope of this document:** SCIM endpoints under `/api/v1/scim/*`.\nThose endpoints conform to RFC 7644 (SCIM 2.0) and follow a different\nenvelope (`schemas`, `Resources`, `totalResults`, etc.). They are\ndocumented separately at /docs/scim-user-management.\n"
x-out-of-scope-note: 'SCIM endpoints (`/api/v1/scim/*`) are NOT included in this spec. They
follow RFC 7644 (SCIM 2.0) and are documented in a separate document at
/docs/scim-user-management.
'
contact:
name: Prezent API Support
email: support@prezent.ai
url: https://prezent.ai
license:
name: Proprietary - Prezent, Inc.
url: https://prezent.ai/terms
servers:
- url: https://api.prezent.ai
description: Production (canonical)
- url: https://uatstage-api.myprezent.com
description: UAT (user acceptance testing)
- url: https://devstage-api.myprezent.com
description: Development
security:
- BearerAuth: []
tags:
- name: Upload
description: Validate, preprocess, and upload supporting files (PowerPoint, PDF, images, etc.).
paths:
/api/v1/upload:
post:
tags:
- Upload
summary: Upload a single file (base64-encoded)
description: 'Accepts a single file as a base64 string or `data:` URL in the
request body. The response contains the uploaded file''s id, S3
path, and metadata.
'
operationId: uploadFile
x-rate-limit-category: general
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UploadFileRequest'
responses:
'200':
description: File uploaded.
content:
application/json:
schema:
$ref: '#/components/schemas/UploadFileResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'415':
$ref: '#/components/responses/UnsupportedFileType'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/InternalServerError'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
/api/v1/preprocess:
post:
tags:
- Upload
summary: Preprocess a file in chunks
description: 'Accepts one chunk of a multi-chunk file upload. The caller drives
chunking via `chunkIndex` and `totalChunks`; chunks for the same
upload share a `requestIdentifier`. Once all chunks for a
`requestIdentifier` have arrived the file is assembled and made
available to downstream operations.
'
operationId: preprocessFile
x-rate-limit-category: general
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PreprocessFileRequest'
responses:
'200':
description: Chunk received.
content:
application/json:
schema:
$ref: '#/components/schemas/PreprocessFileResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'415':
$ref: '#/components/responses/UnsupportedFileType'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/InternalServerError'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
/api/v1/validate:
post:
tags:
- Upload
summary: Validate uploaded files and/or web links
description: 'Validates a set of previously uploaded files (referenced by
`fileIdentifiers`) and/or a list of web links. At least one of
`fileIdentifiers` or `webLinks` must be non-empty.
'
operationId: validateFiles
x-rate-limit-category: general
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ValidateFilesRequest'
responses:
'200':
description: Validation result returned.
content:
application/json:
schema:
$ref: '#/components/schemas/ValidateFilesResponse'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
'415':
$ref: '#/components/responses/UnsupportedFileType'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/InternalServerError'
'503':
$ref: '#/components/responses/ServiceUnavailable'
'504':
$ref: '#/components/responses/GatewayTimeout'
components:
responses:
InternalServerError:
description: Unexpected server error. `error.code` is `INTERNAL_SERVER_ERROR`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: INTERNAL_SERVER_ERROR
message: An unexpected server error occurred.
details: {}
UnsupportedFileType:
description: Uploaded file's extension or MIME type is not accepted. `error.code` is `UNSUPPORTED_FILE_TYPE`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: UNSUPPORTED_FILE_TYPE
message: Unsupported file type.
details: {}
Unauthorized:
description: 'Caller did not present a valid Bearer token, or the token has
expired. `error.code` is one of `UNAUTHORIZED`, `INVALID_API_KEY`,
`EXPIRED_API_KEY`.
'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: INVALID_API_KEY
message: API key not found or not authorized.
details: {}
Forbidden:
description: Caller is authenticated but not allowed to perform this operation. `error.code` is `FORBIDDEN`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: FORBIDDEN
message: Access to the resource is forbidden.
details: {}
RateLimited:
description: "Rate limit, usage limit, or gateway-level throttle exceeded.\n`error.code` is `TOO_MANY_REQUESTS` (gateway throttle),\n`RATE_LIMIT_EXCEEDED` (per-category), or `USAGE_LIMIT_EXCEEDED`\n(annual quota).\n\nDefault limits (all configurable per company/key):\n- Gateway throttle (per API key) → `TOO_MANY_REQUESTS`: 10 requests/second\n sustained, 5 burst, 1,000 requests/day.\n- Per-company, per-category sliding 60-second window →\n `RATE_LIMIT_EXCEEDED`. The applicable category is given by each\n operation's `x-rate-limit-category`.\n- Annual usage quota → `USAGE_LIMIT_EXCEEDED`: 50,000 slide\n generations/year and 1,000,000 presentation downloads/year.\n\n`X-RateLimit-Limit`/`X-RateLimit-Remaining`/`X-RateLimit-Reset` are\nreturned on successful (2xx) responses from rate-limited endpoints\nand, with `Retry-After`, on the per-category `RATE_LIMIT_EXCEEDED`\n429 (the headers declared below). The gateway `TOO_MANY_REQUESTS`\nand annual `USAGE_LIMIT_EXCEEDED` responses do not carry them. Read\n`X-RateLimit-Remaining` to self-throttle and honour `Retry-After` on\na 429.\n"
headers:
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
Retry-After:
$ref: '#/components/headers/RetryAfter'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: RATE_LIMIT_EXCEEDED
message: Rate limit exceeded for this category. Try again later.
details:
category: auto_generator
retry_after_seconds: 12
BadRequest:
description: Generic client error. `error.code` is one of `BAD_REQUEST`, `INVALID_JSON`, `MISSING_REQUIRED_FIELD`, `MISSING_QUERY_PARAM`, `MISSING_CALLBACK_ID`, `MISSING_SLIDES_ARRAY`, `MISSING_PROMPT`, `MISSING_TEMPLATE_ID`, `MISSING_FILE_CONTENT`, `MISSING_SHARE_DETAILS`, `INVALID_TYPE`, `INVALID_DATA`, `INVALID_DATA_TYPE`, `INVALID_PAYLOAD`, `INVALID_REQUEST`, `API_REQUEST_FAILED`, or `FILE_UPLOAD_FAILED`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: BAD_REQUEST
message: Bad request.
details: {}
NotFound:
description: 'Requested endpoint or resource does not exist. `error.code` is
one of `ENDPOINT_NOT_FOUND`, `RESOURCE_NOT_FOUND`, `NOT_FOUND`.
'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: RESOURCE_NOT_FOUND
message: The requested resource was not found.
details: {}
UnprocessableEntity:
description: 'Request was well-formed but failed semantic validation.
`error.code` is one of `INVALID_INPUT`, `UNPROCESSABLE_ENTITY`.
'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: INVALID_INPUT
message: Invalid input provided.
details: {}
GatewayTimeout:
description: A downstream call timed out. `error.code` is `GATEWAY_TIMEOUT`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: GATEWAY_TIMEOUT
message: Gateway timeout.
details: {}
ServiceUnavailable:
description: Service is temporarily unavailable (downstream dependency unhealthy). `error.code` is `SERVICE_UNAVAILABLE` or `EXTERNAL_SERVICE_ERROR`.
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorEnvelope'
example:
success: false
data: null
error:
code: SERVICE_UNAVAILABLE
message: Service is temporarily unavailable.
details: {}
schemas:
ErrorEnvelope:
type: object
description: 'Standard error envelope returned by every documented endpoint
(both in-Lambda and gateway-level errors). Additional legacy
keys may appear alongside `success`/`data`/`error` for
backwards compatibility.
'
required:
- success
- data
- error
properties:
success:
type: boolean
const: false
description: Always `false` on error.
data:
type:
- object
- 'null'
description: Always `null` on error.
error:
type: object
required:
- code
- message
description: Error description.
properties:
code:
$ref: '#/components/schemas/ErrorCode'
message:
type: string
description: Human-readable error description (English).
details:
type: object
description: Optional structured details (validation failures, downstream-service info, etc.).
additionalProperties: true
additionalProperties: true
ValidateFilesResponse:
description: Response body for `POST /api/v1/validate`.
allOf:
- $ref: '#/components/schemas/SuccessEnvelope'
- type: object
properties:
data:
type: object
properties:
files:
type: array
description: Per-file validation results.
items:
type: object
properties:
uuid:
type: string
description: File uuid.
file_name:
type: string
description: Original filename.
valid:
type: boolean
description: Whether the file passed validation.
reason:
type: string
description: Failure reason when `valid=false`.
additionalProperties: true
web_links:
type: array
description: Per-link validation results.
items:
type: object
properties:
url:
type: string
description: The link.
valid:
type: boolean
description: Whether the link is reachable and ingestable.
reason:
type: string
description: Failure reason when `valid=false`.
additionalProperties: true
message:
type: string
description: Human-readable confirmation.
additionalProperties: true
PreprocessFileResponse:
description: Response body for `POST /api/v1/preprocess` and `POST /api/v1/template-converter/preprocess`.
allOf:
- $ref: '#/components/schemas/SuccessEnvelope'
- type: object
properties:
data:
type: object
required:
- request_identifier
- file_name
properties:
request_identifier:
type: string
description: The caller-supplied identifier.
file_name:
type: string
description: The filename that was processed.
message:
type: string
description: Human-readable confirmation.
additionalProperties: true
UploadFileRequest:
type: object
description: Request body for `POST /api/v1/upload`.
required:
- fileContent
- fileName
properties:
fileContent:
type: string
description: File content as a base64 string or `data:` URL.
fileName:
type: string
description: Original filename including extension.
additionalProperties: true
ErrorCode:
type: string
description: 'Stable identifier for an error condition. Codes never change
meaning or HTTP status once published.
'
enum:
- INVALID_API_KEY
- EXPIRED_API_KEY
- UNAUTHORIZED
- FORBIDDEN
- ENDPOINT_NOT_FOUND
- RESOURCE_NOT_FOUND
- NOT_FOUND
- METHOD_NOT_ALLOWED
- UNSUPPORTED_FILE_TYPE
- INVALID_INPUT
- UNPROCESSABLE_ENTITY
- RATE_LIMIT_EXCEEDED
- USAGE_LIMIT_EXCEEDED
- TOO_MANY_REQUESTS
- THROTTLED
- BAD_REQUEST
- INVALID_JSON
- MISSING_REQUIRED_FIELD
- MISSING_QUERY_PARAM
- MISSING_CALLBACK_ID
- MISSING_SLIDES_ARRAY
- MISSING_PROMPT
- MISSING_TEMPLATE_ID
- MISSING_FILE_CONTENT
- MISSING_SHARE_DETAILS
- INVALID_TYPE
- INVALID_DATA
- INVALID_DATA_TYPE
- INVALID_PAYLOAD
- INVALID_REQUEST
- API_REQUEST_FAILED
- FILE_UPLOAD_FAILED
- MAX_RETRIES_EXCEEDED
- EXTERNAL_SERVICE_ERROR
- INTERNAL_SERVER_ERROR
- SERVICE_UNAVAILABLE
- GATEWAY_TIMEOUT
ValidateFilesRequest:
type: object
description: 'Request body for `POST /api/v1/validate`. At least one of
`fileIdentifiers` or `webLinks` must be non-empty.
'
properties:
fileIdentifiers:
type: object
description: Map of `uuid` → `fileName` for previously uploaded files.
additionalProperties:
type: string
description: Original filename for that uuid.
webLinks:
type: array
description: List of URLs to validate.
items:
type: string
format: uri
additionalProperties: true
PreprocessFileRequest:
type: object
description: Request body for `POST /api/v1/preprocess` and `POST /api/v1/template-converter/preprocess`.
required:
- fileContent
- fileName
- chunkIndex
- totalChunks
- requestIdentifier
properties:
fileContent:
type: string
description: Chunk content as base64 / `data:` URL.
fileName:
type: string
description: Original filename including extension.
chunkIndex:
type: integer
minimum: 0
description: Zero-based index of this chunk.
totalChunks:
type: integer
minimum: 1
description: Total number of chunks for this upload.
requestIdentifier:
type: string
description: Caller-supplied identifier that groups chunks of the same upload.
additionalProperties: true
SuccessEnvelope:
type: object
description: 'Standard success envelope. Endpoint-specific schemas extend this
and constrain the `data` property to their concrete shape.
Additional legacy keys (`status`, `log`, …) may appear alongside
`success`/`data` for backwards compatibility, and some legacy
handlers omit `success`, so it is not marked required.
'
required:
- data
properties:
success:
type: boolean
description: '`true` on success (omitted by some legacy handlers).'
data:
type: object
description: Endpoint-specific payload.
additionalProperties: true
UploadFileResponse:
description: Response body for `POST /api/v1/upload`.
allOf:
- $ref: '#/components/schemas/SuccessEnvelope'
- type: object
properties:
data:
type: object
required:
- file
properties:
file:
type: object
required:
- file_id
- file_name
- file_type
- s3_path
- s3_bucket
properties:
file_id:
type: string
description: Internal id of the uploaded file.
file_name:
type: string
description: Original filename.
file_type:
type: string
description: MIME type / detected file type.
s3_path:
type: string
description: S3 key of the uploaded file.
s3_bucket:
type: string
description: S3 bucket of the uploaded file.
additionalProperties: true
message:
type: string
description: Human-readable confirmation.
additionalProperties: true
headers:
RetryAfter:
description: Number of seconds the client should wait before retrying.
schema:
type: integer
format: int32
minimum: 0
XRateLimitLimit:
description: 'The configured request limit for the rate-limit category
(requests per 60-second window) that applied to this call.
The applicable category is the operation''s `x-rate-limit-category`.
Returned on every response (success and 429) so clients can
self-throttle. See the Rate limits guide for the default
per-category numbers.
'
schema:
type: integer
format: int32
minimum: 0
XRateLimitReset:
description: Unix timestamp (seconds) when the current rate-limit window resets.
schema:
type: integer
format: int64
minimum: 0
XRateLimitRemaining:
description: 'Approximate number of requests remaining in the current
60-second window for this caller and category.
'
schema:
type: integer
format: int32
minimum: 0
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: opaque
description: 'Bearer token authentication. Supply the API key issued by
Customer Success as `Authorization: Bearer <api_key>`. The API
does NOT accept the AWS `x-api-key` header. Keys may have an
expiry date; expired keys return `401 EXPIRED_API_KEY`. Keys are
scoped to specific paths; calling an unauthorised path returns
`404 ENDPOINT_NOT_FOUND`.
'