Skip to main content
This guide shows you how to feed Pictory documentation to a Large Language Model (LLM) so the model can guide a user end-to-end — from describing a video they want, through building the right API payload, to retrieving the rendered video. By the end of this page, you will have:
  • A single URL you can paste into any LLM to make it Pictory-aware
  • A system prompt that turns the model into a Pictory API assistant
  • A reference list of example user prompts and the API calls they should produce
  • A working setup for the Pictory MCP server so agentic tools can call the API directly

Why This Matters

The Pictory API exposes many endpoints, dozens of optional fields, and several content-source types (text, blog URLs, PowerPoint, audio, video). A user describing their goal in natural language (“create a 60-second product demo with a chef avatar”) needs a lot of context to be translated correctly into a request payload. LLMs handle this translation well — when given the right context. The pieces below give an LLM that context.

1. Point an LLM at llms.txt or llms-full.txt

Pictory’s documentation site automatically generates two machine-friendly bundles you can feed to any LLM:
FileURLWhat It ContainsWhen to Use
llms.txthttps://docs.pictory.ai/llms.txtIndex of all docs pages with titles and one-line descriptionsQuick navigation, smaller context windows
llms-full.txthttps://docs.pictory.ai/llms-full.txtEntire documentation site concatenated into one Markdown fileMaximum accuracy, large context windows

How to Use

Option A — Paste into a chat session. Open any LLM chat (Claude, ChatGPT, Perplexity, Gemini) and paste the URL or the contents of llms-full.txt at the top of the conversation. Then ask your question normally. Option B — Use the per-page Copy/Open buttons. Every page on docs.pictory.ai has a “Copy” menu in the top-right with these options: Copy as Markdown, Open in ChatGPT, Open in Claude, Open in Perplexity, Open in MCP, Open in Cursor, Open in VSCode. Use these when you need context from a single page. Option C — Reference the URL programmatically. If you are building an agent or chatbot, fetch llms-full.txt once per session and pass it as a system prompt or context block:
const docsContext = await fetch("https://docs.pictory.ai/llms-full.txt")
  .then((r) => r.text());

const systemPrompt = `${PICTORY_SYSTEM_PROMPT}\n\n## Pictory Docs\n\n${docsContext}`;
llms-full.txt is large. If your model’s context window is small, prefer llms.txt and use the per-page Markdown URLs for the specific pages the user’s question touches.

2. Use the Pictory OpenAPI Spec

For deterministic codegen and structured tool use, the Pictory API publishes an OpenAPI 3.1 specification: https://docs.pictory.ai/openapi.json You can:
  • Feed this directly to an LLM as a structured tool schema
  • Generate client SDKs in any language (TypeScript, Python, Go, Ruby, etc.) using openapi-generator or openapi-typescript
  • Import into Postman, Insomnia, or any API client for interactive testing
When you give an LLM both the OpenAPI spec and llms-full.txt, you get the best of both worlds — the structured field-level validation from OpenAPI, plus the narrative guidance and examples from the docs.

Paste this as the system prompt (or the first message) in any LLM you want to act as a Pictory API assistant:
You are a Pictory API assistant. You help users create videos programmatically using the Pictory API.

## Core Knowledge

- **Authentication:** The Pictory API uses a direct API key in the `Authorization` header. The key starts with `pictai_`. Do NOT use a `Bearer` prefix. The header value is the raw key.
- **Base URL:** `https://api.pictory.ai/pictoryapis`
- **Primary endpoints:**
  - `POST /v2/video/storyboard` — Create a storyboard preview (review before rendering)
  - `POST /v2/video/storyboard/render` — Render the final video directly
  - `POST /v2/projects/{projectid}/render` — Re-render an existing project
  - `GET /v1/jobs/{jobid}` — Fetch the status and output of any job
  - `GET /v1/brands/video` — List the user's video brand kits

## How to Help

1. Ask the user what they want to create (text-to-video, PPT-to-video, avatar video, template-based, etc.).
2. Identify the right endpoint based on the input source.
3. Build a complete, valid request payload — never use placeholder values for required fields without flagging them.
4. Surface mutually exclusive fields (e.g., `brandId` vs `brandName`, `smartLayoutId` vs `smartLayoutName`, `subtitleStyleId` vs `subtitleStyleName`).
5. Always show how to poll the job status using `GET /v1/jobs/{jobid}` afterward, OR recommend the `webhook` field for async notification.
6. Include language hints when relevant. Supported `language` values: `zh, nl, en, fr, de, hi, it, ja, ko, mr, pt, ru, es, ta`.

## Dynamic IDs — Never Invent These

The following fields take **account-scoped IDs that must be discovered at runtime**. Do NOT hallucinate values; do NOT memorize examples from training data. Call the discovery endpoint first, then use a real ID from the response.

| Field | Discovery endpoint | Notes |
|---|---|---|
| `avatar.avatarId` | `GET /v1/avatars` | Lists AI avatars available to the user's account |
| `brandId` / `brandName` | `GET /v1/brands/video` | Lists the user's saved brand kits |
| `templateId` | `GET /v2/projects` or `GET /v1/templates` | Either an existing project ID (used as a template) or a saved template ID |
| `smartLayoutId` / `smartLayoutName` | `GET /v1/smartlayouts` | Lists available smart layouts |
| `subtitleStyleId` / `subtitleStyleName` | `GET /v1/styles` | Lists saved subtitle styles |
| `voiceOver.aiVoices[].speaker` | `GET /v1/voiceovers/tracks` | Lists available AI voices |

**Workflow:** when a user says "use my chef avatar", do not guess an ID. Either ask them for the ID explicitly, or instruct them to run `GET /v1/avatars` and pick from the response. The same applies to brands, templates, layouts, subtitle styles, and voices.

### Default Voice by Language

When the user does not specify a voice but does specify a language, use the documented default male STD voice for that language. For languages without a documented default, the API falls back to the English default; in that case it is often better to call `GET /v1/voiceovers/tracks` and pick a native-language voice explicitly.

| `language` | Default male STD voice | Notes |
|---|---|---|
| `en` | `Martin` | |
| `nl` | `Tim` | Dutch |
| `fr` | `Gabriel` | French |
| `de` | `Wilbur` | German |
| `it` | `Marco` | Italian |
| `pt` | `Aurelio` | Portuguese |
| `es` | `Hugo` | Spanish |
| `hi` | `Martin` | Hindi — falls back to English |
| `ru` | `Martin` | Russian — falls back to English |
| `zh`, `ja`, `ko`, `mr`, `ta` | (none documented) | Discover a native voice via `GET /v1/voiceovers/tracks` |

This table covers the documented STD male defaults. For female voices or non-default catalogs, call the voiceovers tracks endpoint and let the user choose.

## Output Format

When generating an API call, always output:

1. A short summary of what the call will do (one sentence).
2. The complete cURL command (with `YOUR_API_KEY` as the placeholder).
3. A note about the response shape and how to retrieve the rendered video.

## Common Pitfalls to Avoid

- Do not invent endpoints. If you are unsure, ask the user to confirm or reference the docs.
- Do not invent or hallucinate IDs (`avatarId`, `brandId`, `templateId`, `smartLayoutId`, `subtitleStyleId`, voice `speaker`). Always discover them via the listing endpoints above.
- Do not use `Bearer` in the Authorization header — Pictory uses the raw key.
- Do not omit `videoName` (required) on render endpoints.
- Do not include both `brandId` and `brandName` in the same request — the API rejects this.
- Do not place `avatarId` inside a scene's `avatar` field. The avatar identity is set once at the top level (`avatar.avatarId`); per-scene `avatar` accepts only position and styling overrides.
- API render jobs are NOT saved as projects unless `saveProject: true` is passed (or `templateId` is provided to render against an existing project).

## Reference Documentation

For complete details, refer to `https://docs.pictory.ai/llms-full.txt` and `https://docs.pictory.ai/openapi.json`.

4. Pictory MCP Server

For agentic LLM tools (Claude Desktop, Cursor, Windsurf, custom agents built on the MCP protocol), Pictory provides an MCP server that exposes the API as structured tools. The agent can invoke endpoints directly without you having to handcraft requests. Learn more and grab the connection details at Pictory MCP Server. Setup pages for popular agentic tools:

5. Example Prompts and Expected API Calls

These examples show the natural-language input a user might give and the API call an LLM (configured per the system prompt above) should produce.

Example 1 — Simple text-to-video

“Create a 30-second product demo video about our new coffee maker. Use an upbeat AI voice.”
Expected endpoint: POST /v2/video/storyboard/render
{
  "videoName": "Coffee Maker Demo",
  "language": "en",
  "aspectRatio": "16:9",
  "scenes": [
    { "story": "Introducing the BrewMax 3000 — your morning, simplified.", "createSceneOnEndOfSentence": true },
    { "story": "One-touch brewing, three temperature presets, and a sleek glass carafe.", "createSceneOnEndOfSentence": true },
    { "story": "BrewMax 3000. Order yours today.", "createSceneOnEndOfSentence": true }
  ],
  "voiceOver": {
    "enabled": true,
    "aiVoices": [{ "speaker": "Martin", "speed": 100, "amplificationLevel": 0 }]
  }
}

Example 2 — PPT-to-video in another language

“Convert this PowerPoint deck into a French training video with speaker notes as narration: https://example.com/training.pptx
Expected endpoint: POST /v2/video/storyboard/render
{
  "videoName": "French Training Video",
  "language": "fr",
  "scenes": [
    {
      "pptUrl": "https://example.com/training.pptx",
      "useSpeakerNotes": true
    }
  ],
  "voiceOver": {
    "enabled": true,
    "aiVoices": [{ "speaker": "Gabriel", "speed": 100, "amplificationLevel": 0 }]
  }
}

Example 3 — Avatar video using a saved template

“Use my brand template and render a video where my Chef avatar walks through 4 recipe steps.”
Before generating the payload, the LLM should fetch the available avatars and templates so it uses real IDs from the user’s account:
curl -H 'Authorization: YOUR_API_KEY' https://api.pictory.ai/pictoryapis/v1/avatars
curl -H 'Authorization: YOUR_API_KEY' https://api.pictory.ai/pictoryapis/v2/projects
Then build the payload with real IDs (the placeholders below are stand-ins for values picked from the discovery responses): Expected endpoint: POST /v2/video/storyboard/render
{
  "videoName": "Recipe — Lemon Risotto",
  "templateId": "<projectId from /v2/projects>",
  "avatar": {
    "avatarId": "<avatarId from /v1/avatars>"
  },
  "scenes": [
    { "story": "Today we are making lemon risotto. Here are the ingredients." },
    { "story": "Step 1: Heat the pan and toast the rice." },
    { "story": "Step 2: Add lemon zest and stock, stirring continuously." },
    { "story": "Step 3: Plate and serve with parmesan." }
  ]
}

Example 4 — Blog URL to video

“Turn this blog post into a one-minute video with subtitles: https://example.com/blog/our-launch
Expected endpoint: POST /v2/video/storyboard/render
{
  "videoName": "Blog to Video — Launch Post",
  "language": "en",
  "aspectRatio": "16:9",
  "scenes": [
    {
      "blogUrl": "https://example.com/blog/our-launch"
    }
  ],
  "voiceOver": {
    "enabled": true,
    "aiVoices": [{ "speaker": "Martin", "speed": 100, "amplificationLevel": 0 }]
  }
}
The Pictory backend fetches and summarizes the blog content automatically. The resulting scenes are derived from the article structure. Each scene in the scenes array must contain exactly one content source — story, blogUrl, pptUrl, audioUrl, videoUrl, or storyCoPilot — never mix sources within a single scene.

Example 5 — Storyboard preview, then render-from-preview

“Generate a preview first so I can review the scenes before paying for a full render.”
This is a two-step flow. The LLM should produce both steps. Step 1 — Create the preview: Expected endpoint: POST /v2/video/storyboard
{
  "videoName": "Preview-First Demo",
  "language": "en",
  "scenes": [
    { "story": "First scene narration text.", "createSceneOnEndOfSentence": true },
    { "story": "Second scene narration text.", "createSceneOnEndOfSentence": true }
  ],
  "voiceOver": {
    "enabled": true,
    "aiVoices": [{ "speaker": "Martin", "speed": 100, "amplificationLevel": 0 }]
  }
}
The response contains a jobId. Poll GET /v1/jobs/{jobid} until the preview is completed; the response includes the storyboard scenes and metadata. Step 2 — Render from the preview: Expected endpoint: PUT /v2/video/render/{storyboardjobid}
curl --request PUT \
  --url 'https://api.pictory.ai/pictoryapis/v2/video/render/<storyboardjobid from Step 1>' \
  --header 'Authorization: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{ "webhook": "https://your-domain.com/pictory-webhook" }'
The path parameter is the preview job ID from Step 1, not a project ID. The request body is optional — pass webhook here only if you want to override the webhook URL set during the preview step. Use this two-step flow when the user wants to review or edit scenes before committing render resources. To edit scenes between the two steps, see the Update Storyboard Elements API.

Example 6 — Polling job status

“How do I check if my video at job ID 9b1c4d2e-7f8a-4321-b2c3-d456e789f012 is done?”
Expected endpoint: GET /v1/jobs/{jobid}
curl --request GET \
  --url 'https://api.pictory.ai/pictoryapis/v1/jobs/9b1c4d2e-7f8a-4321-b2c3-d456e789f012' \
  --header 'Authorization: YOUR_API_KEY'
Poll every 10–30 seconds. When data.status === "completed", the rendered video URL is in data.videoURL. For long-running renders, prefer passing a webhook URL in the render request body instead of polling.

6. Troubleshooting LLM Output

SymptomCauseFix
LLM uses Bearer YOUR_API_KEYDefault training bias toward OAuth/Bearer flowsRestate the auth rule in your system prompt: “The Authorization header value is the raw key, no prefix.”
LLM invents an endpointInsufficient contextFeed llms-full.txt or openapi.json into the session
Render succeeds but video does not appear in My ProjectsMissing saveProject: true and no templateIdTell the LLM: “Always include saveProject: true unless the user passes a projectId as templateId.”
LLM passes both brandId and brandNameField-level constraint not in training dataReinforce in system prompt; the API rejects both-together
Polling returns 404Wrong job type or wrong accountVerify the API key matches the account that submitted the job

Next Steps

MCP Server

Connect agentic tools directly to the Pictory API

Claude Code Setup

Wire Claude Code into the Pictory API

Cursor Setup

Configure Cursor to call Pictory endpoints

Windsurf Setup

Configure Windsurf for Pictory automation

End-to-End Recipes

Complete working JSON payloads for common use cases

API Reference

Endpoint-by-endpoint reference