Create Template
curl --request POST \
--url https://api.pictory.ai/pictoryapis/v1/templates \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '{}'import requests
url = "https://api.pictory.ai/pictoryapis/v1/templates"
payload = {}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({})
};
fetch('https://api.pictory.ai/pictoryapis/v1/templates', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pictory.ai/pictoryapis/v1/templates",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.pictory.ai/pictoryapis/v1/templates"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.pictory.ai/pictoryapis/v1/templates")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pictory.ai/pictoryapis/v1/templates")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"templateId": "tmpl_abc123xyz",
"name": "Pending Loan Payment",
"language": "en",
"published": true,
"deprecated": false,
"audio": {
"musicUrl": "https://cdn.pictory.ai/music/background-track.mp3",
"musicVolume": 50,
"aiVoice": {
"voiceId": "en-US-Standard-A",
"speed": 100
}
},
"scenes": [
{
"sceneId": "scene_001",
"subtitles": [
{
"text": "Dear {{customer_name}}, your payment is due on {{payment_date}}"
}
],
"backgroundVisual": {
"type": "video",
"url": "https://cdn.pictory.ai/visuals/payment-reminder.mp4"
}
}
],
"variables": {
"customer_name": "John Doe",
"payment_date": "2024-01-15",
"loan_account_number": "LOAN-12345",
"customer_support_number": "1-800-555-0123",
"support_email_id": "support@example.com"
}
}
{
"success": false,
"message": "Invalid file format. Please upload a .pictai file"
}
{
"message": "Unauthorized"
}
{
"success": false,
"message": "File size exceeds maximum allowed limit"
}
Video Templates
Create Template
Upload a Pictory project file to create a reusable video template
POST
/
pictoryapis
/
v1
/
templates
Create Template
curl --request POST \
--url https://api.pictory.ai/pictoryapis/v1/templates \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '{}'import requests
url = "https://api.pictory.ai/pictoryapis/v1/templates"
payload = {}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({})
};
fetch('https://api.pictory.ai/pictoryapis/v1/templates', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pictory.ai/pictoryapis/v1/templates",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.pictory.ai/pictoryapis/v1/templates"
payload := strings.NewReader("{}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.pictory.ai/pictoryapis/v1/templates")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pictory.ai/pictoryapis/v1/templates")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{}"
response = http.request(request)
puts response.read_body{
"templateId": "tmpl_abc123xyz",
"name": "Pending Loan Payment",
"language": "en",
"published": true,
"deprecated": false,
"audio": {
"musicUrl": "https://cdn.pictory.ai/music/background-track.mp3",
"musicVolume": 50,
"aiVoice": {
"voiceId": "en-US-Standard-A",
"speed": 100
}
},
"scenes": [
{
"sceneId": "scene_001",
"subtitles": [
{
"text": "Dear {{customer_name}}, your payment is due on {{payment_date}}"
}
],
"backgroundVisual": {
"type": "video",
"url": "https://cdn.pictory.ai/visuals/payment-reminder.mp4"
}
}
],
"variables": {
"customer_name": "John Doe",
"payment_date": "2024-01-15",
"loan_account_number": "LOAN-12345",
"customer_support_number": "1-800-555-0123",
"support_email_id": "support@example.com"
}
}
{
"success": false,
"message": "Invalid file format. Please upload a .pictai file"
}
{
"message": "Unauthorized"
}
{
"success": false,
"message": "File size exceeds maximum allowed limit"
}
Overview
Upload a Pictory project file (.pictai) downloaded from the Pictory web app to create a reusable video template. Templates allow you to standardize video creation by defining a base structure with customizable variables that can be populated with different content for each video instance.
You need a valid API key to use this endpoint. Get your API key from the API Access page in your Pictory dashboard.
API Endpoint
POST https://api.pictory.ai/pictoryapis/v1/templates
Request Parameters
Headers
string
required
API key for authentication (starts with
pictai_)Authorization: YOUR_API_KEY
string
required
Must be set to
application/octet-stream for file uploadsContent-Type: application/octet-stream
Body Parameters
file
required
The Pictory project file to upload. Must be a
.pictai file exported from the Pictory web application.File Requirements:- Format:
.pictai(Pictory project file) - Source: Downloaded from Pictory web app
- Content: Complete project configuration including scenes, audio, and variables
Response
string
Unique identifier for the created template
string
Name of the template
string
Language code of the template (e.g.,
en for English)boolean
default:true
Whether the template is published and available for use
boolean
default:false
Whether the template has been marked as deprecated
object
array of objects
object
Template variables that can be customized when creating videos from this templateCommon variables:
customer_name- Customer or recipient namepayment_date- Payment or transaction dateloan_account_number- Account or reference numbercustomer_support_number- Support contact numbersupport_email_id- Support email address
Variable names depend on your template design. These are placeholders that will be replaced with actual values when generating videos from the template.
Response Examples
{
"templateId": "tmpl_abc123xyz",
"name": "Pending Loan Payment",
"language": "en",
"published": true,
"deprecated": false,
"audio": {
"musicUrl": "https://cdn.pictory.ai/music/background-track.mp3",
"musicVolume": 50,
"aiVoice": {
"voiceId": "en-US-Standard-A",
"speed": 100
}
},
"scenes": [
{
"sceneId": "scene_001",
"subtitles": [
{
"text": "Dear {{customer_name}}, your payment is due on {{payment_date}}"
}
],
"backgroundVisual": {
"type": "video",
"url": "https://cdn.pictory.ai/visuals/payment-reminder.mp4"
}
}
],
"variables": {
"customer_name": "John Doe",
"payment_date": "2024-01-15",
"loan_account_number": "LOAN-12345",
"customer_support_number": "1-800-555-0123",
"support_email_id": "support@example.com"
}
}
{
"success": false,
"message": "Invalid file format. Please upload a .pictai file"
}
{
"message": "Unauthorized"
}
{
"success": false,
"message": "File size exceeds maximum allowed limit"
}
Code Examples
curl --location 'https://api.pictory.ai/pictoryapis/v1/templates' \
--header 'Authorization: YOUR_API_KEY' \
--header 'Content-Type: application/octet-stream' \
--data-binary '@Pending Loan Payment.pictai' | python -m json.tool
import requests
url = "https://api.pictory.ai/pictoryapis/v1/templates"
headers = {
"Authorization": "YOUR_API_KEY",
"Content-Type": "application/octet-stream"
}
# Upload the .pictai file
with open("Pending Loan Payment.pictai", "rb") as file:
response = requests.post(url, headers=headers, data=file)
result = response.json()
if response.status_code == 200:
template_id = result.get('templateId')
print(f"Template created successfully: {template_id}")
print(f"Template name: {result.get('name')}")
print(f"Variables: {list(result.get('variables', {}).keys())}")
else:
print(f"Failed to create template: {result.get('message')}")
const fs = require('fs');
const url = 'https://api.pictory.ai/pictoryapis/v1/templates';
const filePath = 'Pending Loan Payment.pictai';
// Read the file
const fileBuffer = fs.readFileSync(filePath);
// Upload template
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'YOUR_API_KEY',
'Content-Type': 'application/octet-stream'
},
body: fileBuffer
});
const result = await response.json();
if (response.ok) {
console.log(`Template created: ${result.templateId}`);
console.log(`Template name: ${result.name}`);
console.log(`Variables:`, Object.keys(result.variables || {}));
} else {
console.error(`Failed to create template: ${result.message}`);
}
Usage Notes
File Source: The
.pictai file must be exported from the Pictory web application. You can download project files from your Pictory dashboard.File Size Limits: Ensure your template file is within the allowed size limit. Large files with many high-resolution assets may exceed upload limits.
Template Variables: Design your templates with variables (e.g.,
{{customer_name}}, {{payment_date}}) to make them reusable across different video instances.How to Export a .pictai File
To create a template, you first need to export a project file from the Pictory web app:- Create or Open a Project in the Pictory web application
- Design Your Template with the desired scenes, text, visuals, and audio
- Add Variables using double curly braces (e.g.,
{{variable_name}}) in text fields - Export the Project as a
.pictaifile from the project menu - Upload via API using this endpoint
Template Variables
Variables are placeholders in your template that can be replaced with actual values when creating videos. Use the following format:Variable Syntax
{{variable_name}}
Common Use Cases for Variables
- Personalization: Customer names, account numbers
- Dynamic Dates: Payment dates, deadlines, event dates
- Contact Information: Phone numbers, email addresses, support contacts
- Custom Content: Product names, prices, locations, offers
Example Template Text
Dear {{customer_name}},
Your payment of ${{payment_amount}} is due on {{payment_date}}.
Account Number: {{loan_account_number}}
For assistance, contact us at {{customer_support_number}}
or email {{support_email_id}}.
Common Use Cases
1. Upload Template from File
Upload a template file and handle the response:import requests
def upload_template(file_path, api_key):
"""
Upload a .pictai file to create a template
"""
url = "https://api.pictory.ai/pictoryapis/v1/templates"
headers = {
"Authorization": api_key,
"Content-Type": "application/octet-stream"
}
try:
with open(file_path, "rb") as file:
response = requests.post(url, headers=headers, data=file)
if response.status_code == 200:
template = response.json()
print(f"✓ Template created: {template['name']}")
print(f" Template ID: {template['templateId']}")
print(f" Language: {template['language']}")
print(f" Scenes: {len(template.get('scenes', []))}")
print(f" Variables: {', '.join(template.get('variables', {}).keys())}")
return template
else:
error = response.json()
print(f"✗ Upload failed: {error.get('message')}")
return None
except FileNotFoundError:
print(f"✗ File not found: {file_path}")
return None
except Exception as e:
print(f"✗ Error: {str(e)}")
return None
# Example usage
template = upload_template(
"Pending Loan Payment.pictai",
"YOUR_API_KEY",
user_id="user_12345"
)
2. Batch Upload Multiple Templates
Upload multiple template files at once:import os
import requests
from pathlib import Path
def batch_upload_templates(directory, api_key):
"""
Upload all .pictai files from a directory
"""
url = "https://api.pictory.ai/pictoryapis/v1/templates"
headers = {
"Authorization": api_key,
"Content-Type": "application/octet-stream"
}
# Find all .pictai files
template_files = list(Path(directory).glob("*.pictai"))
if not template_files:
print("No .pictai files found in directory")
return []
results = []
for file_path in template_files:
print(f"Uploading: {file_path.name}")
try:
with open(file_path, "rb") as file:
response = requests.post(url, headers=headers, data=file)
if response.status_code == 200:
template = response.json()
results.append({
'file': file_path.name,
'status': 'success',
'template_id': template['templateId'],
'name': template['name']
})
print(f" ✓ Success: {template['templateId']}")
else:
error = response.json()
results.append({
'file': file_path.name,
'status': 'failed',
'error': error.get('message')
})
print(f" ✗ Failed: {error.get('message')}")
except Exception as e:
results.append({
'file': file_path.name,
'status': 'error',
'error': str(e)
})
print(f" ✗ Error: {str(e)}")
# Print summary
successful = sum(1 for r in results if r['status'] == 'success')
print(f"\nSummary: {successful}/{len(results)} templates uploaded successfully")
return results
# Example usage
results = batch_upload_templates(
"./templates",
"YOUR_API_KEY",
user_id="user_12345"
)
3. Upload and Extract Template Info
Upload a template and extract key information:const fs = require('fs');
async function uploadAndAnalyzeTemplate(filePath, apiKey) {
const url = 'https://api.pictory.ai/pictoryapis/v1/templates';
const headers = {
'Authorization': `${apiKey}`,
'Content-Type': 'application/octet-stream'
};
try {
// Read and upload file
const fileBuffer = fs.readFileSync(filePath);
const response = await fetch(url, {
method: 'POST',
headers,
body: fileBuffer
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Upload failed');
}
const template = await response.json();
// Extract template information
const info = {
id: template.templateId,
name: template.name,
language: template.language,
sceneCount: template.scenes?.length || 0,
variables: Object.keys(template.variables || {}),
hasMusic: Boolean(template.audio?.musicUrl),
hasAiVoice: Boolean(template.audio?.aiVoice),
published: template.published
};
console.log('Template Created:', info);
return info;
} catch (error) {
console.error('Upload failed:', error.message);
return null;
}
}
// Example usage
const info = await uploadAndAnalyzeTemplate(
'Pending Loan Payment.pictai',
'YOUR_API_KEY',
'user_12345'
);
4. Upload with Validation
Validate the file before uploading:import os
import requests
from pathlib import Path
def validate_and_upload_template(file_path, api_key):
"""
Validate template file before upload
"""
# Validation checks
if not os.path.exists(file_path):
return {'success': False, 'error': 'File does not exist'}
if not file_path.endswith('.pictai'):
return {'success': False, 'error': 'File must be a .pictai file'}
file_size = os.path.getsize(file_path)
max_size = 50 * 1024 * 1024 # 50 MB
if file_size > max_size:
return {
'success': False,
'error': f'File size ({file_size / 1024 / 1024:.1f} MB) exceeds limit'
}
if file_size == 0:
return {'success': False, 'error': 'File is empty'}
# Upload
url = "https://api.pictory.ai/pictoryapis/v1/templates"
headers = {
"Authorization": api_key,
"Content-Type": "application/octet-stream"
}
print(f"Uploading {Path(file_path).name} ({file_size / 1024:.1f} KB)...")
try:
with open(file_path, "rb") as file:
response = requests.post(url, headers=headers, data=file)
if response.status_code == 200:
template = response.json()
return {
'success': True,
'template': template,
'template_id': template['templateId']
}
else:
error = response.json()
return {
'success': False,
'error': error.get('message', 'Upload failed')
}
except Exception as e:
return {'success': False, 'error': str(e)}
# Example usage
result = validate_and_upload_template(
"template.pictai",
"YOUR_API_KEY",
user_id="user_12345"
)
if result['success']:
print(f"Success! Template ID: {result['template_id']}")
else:
print(f"Error: {result['error']}")
5. Upload with Progress Tracking
Upload large templates with progress indication:import requests
from tqdm import tqdm
class ProgressFileReader:
def __init__(self, file_path):
self.file_path = file_path
self.file_size = os.path.getsize(file_path)
self.file = open(file_path, 'rb')
self.progress = tqdm(total=self.file_size, unit='B', unit_scale=True)
def read(self, size=-1):
data = self.file.read(size)
self.progress.update(len(data))
return data
def __enter__(self):
return self
def __exit__(self, *args):
self.file.close()
self.progress.close()
def upload_template_with_progress(file_path, api_key):
"""
Upload template with progress bar
"""
url = "https://api.pictory.ai/pictoryapis/v1/templates"
headers = {
"Authorization": api_key,
"Content-Type": "application/octet-stream"
}
print(f"Uploading {os.path.basename(file_path)}...")
with ProgressFileReader(file_path) as file:
response = requests.post(url, headers=headers, data=file)
if response.status_code == 200:
template = response.json()
print(f"\n✓ Upload complete: {template['templateId']}")
return template
else:
error = response.json()
print(f"\n✗ Upload failed: {error.get('message')}")
return None
# Example usage
template = upload_template_with_progress(
"large-template.pictai",
"YOUR_API_KEY"
)
Best Practices
File Management
- Organize Templates: Keep template files organized by category or purpose
- Version Control: Maintain version history of template files
- Naming Convention: Use descriptive names for template files
- Backup: Keep backups of all template files
- Documentation: Document the purpose and variables of each template
Template Design
- Use Meaningful Variables: Choose clear, descriptive variable names
- Consistent Naming: Use a consistent naming convention for variables (e.g.,
snake_case) - Default Values: Provide sensible default values in the template
- Test Thoroughly: Test templates with various variable values before uploading
- Optimize Assets: Keep file sizes reasonable by optimizing images and videos
Error Handling
- Validate Files: Check file format and size before uploading
- Handle Failures: Implement retry logic for network failures
- Log Uploads: Keep records of uploaded templates
- Monitor Limits: Track upload quotas and limits
- Verify Results: Confirm template creation by checking the response
Was this page helpful?
