Guide
Files and uploads
Send source files as base64-encoded entries in the uploads array.
There is no separate upload step and no multipart form. You put the bytes in the request, in an uploads array of { fileBase64, fileName } objects. This keeps MCP and REST identical, since an MCP tool call cannot carry a multipart body.
#Limits
| Flow | What the file is | Max size | Accepted |
|---|---|---|---|
deck | One deck to redesign. Set options.mode to make it an enhance | 50 MB | .pdf .pptx |
recording-edit | The recording to cut. Required | 500 MB | .mp4 .webm .mov .mkv .avi |
demo-video | Optional assets the agent turns into a slideshow | 50 MB each | .pdf .png .jpg .jpeg .webp |
fileName, not from the bytes.#Sending a file
curl -X POST https://api.trypitch.co/v1/projects \
-H "Authorization: Bearer pk_your_key" \
-H "Content-Type: application/json" \
-d "$(jq -n \
--arg f "$(base64 -w0 deck.pdf)" \
'{ prompt: "Modernise it, keep the story",
options: { mode: "recreate" },
uploads: [{ fileBase64: $f, fileName: "deck.pdf" }] }')"import { readFile } from "node:fs/promises"
const file = await readFile("recording.mp4")
const res = await fetch("https://api.trypitch.co/v1/projects", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PITCH_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
prompt: "Cut the dead air at the start. Add intro and outro cards.",
options: { productName: "Acme", productUrl: "https://acme.com" },
uploads: [{ fileBase64: file.toString("base64"), fileName: "recording.mp4" }],
}),
})When you send an upload, prompt may be empty. Otherwise it is required.
#What happens to your file
We decode it to a temp file, check the extension and size, upload it to object storage, and delete the temp copy. The stored copy is what the agent reads into the project workspace. Output files live in the same bucket and are served over HTTPS.
#Assets for a demo video
For demo-video, uploads are optional extras: PDFs or images the agent prepares into a slideshow and cuts between the live browser and the slides. Mention in the prompt what they are for.
{
"prompt": "https://trypitch.co — open with the pricing one-pager, then show sign-up.",
"uploads": [{ "fileBase64": "...", "fileName": "pricing.pdf" }]
}#Errors
| Status | Code | Cause |
|---|---|---|
| 413 | payload_too_large | The decoded file is over the limit for its media type |
| 415 | unsupported_media_type | The extension is not in the accepted media list |
| 400 | invalid_request | The base64 decoded to nothing |