> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pictory.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Template

> Upload a Pictory project file to create a reusable video template

## 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.

<Note>
  You need a valid API key to use this endpoint. Get your API key from the [API Access page](https://app.pictory.ai/api-access) in your Pictory dashboard.
</Note>

## API Endpoint

```http theme={null}
POST https://api.pictory.ai/pictoryapis/v1/templates
```

## Request Parameters

### Headers

<ParamField header="Authorization" type="string" required>
  API key for authentication (starts with `pictai_`)

  ```
  Authorization: YOUR_API_KEY
  ```
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be set to `application/octet-stream` for file uploads

  ```
  Content-Type: application/octet-stream
  ```
</ParamField>

### Body Parameters

<ParamField body="pictoryprojectfile" type="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
</ParamField>

## Response

<ResponseField name="templateId" type="string">
  Unique identifier for the created template
</ResponseField>

<ResponseField name="name" type="string">
  Name of the template
</ResponseField>

<ResponseField name="language" type="string">
  Language code of the template (e.g., `en` for English)
</ResponseField>

<ResponseField name="published" type="boolean" default={true}>
  Whether the template is published and available for use
</ResponseField>

<ResponseField name="deprecated" type="boolean" default={false}>
  Whether the template has been marked as deprecated
</ResponseField>

<ResponseField name="audio" type="object">
  Audio configuration for the template

  <Expandable title="properties">
    <ResponseField name="musicUrl" type="string">
      URL to the background music file
    </ResponseField>

    <ResponseField name="musicVolume" type="number" default={0}>
      Volume level for background music (0-100)
    </ResponseField>

    <ResponseField name="aiVoice" type="object">
      AI voice-over configuration settings
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="scenes" type="array of objects">
  Array of scene objects that make up the template

  <Expandable title="Scene object">
    <ResponseField name="sceneId" type="string">
      Unique identifier for the scene
    </ResponseField>

    <ResponseField name="subtitles" type="array of objects">
      Array of subtitle text objects for the scene

      <Expandable title="Subtitle object">
        <ResponseField name="text" type="string">
          The subtitle text content
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="backgroundVisual" type="object">
      Configuration for the scene's background visual (image or video)
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="variables" type="object">
  Template variables that can be customized when creating videos from this template

  **Common variables:**

  * `customer_name` - Customer or recipient name
  * `payment_date` - Payment or transaction date
  * `loan_account_number` - Account or reference number
  * `customer_support_number` - Support contact number
  * `support_email_id` - Support email address

  <Note>
    Variable names depend on your template design. These are placeholders that will be replaced with actual values when generating videos from the template.
  </Note>
</ResponseField>

## Response Examples

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "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"
    }
  }
  ```

  ```json 400 - Bad Request theme={null}
  {
    "success": false,
    "message": "Invalid file format. Please upload a .pictai file"
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
    "message": "Unauthorized"
  }
  ```

  ```json 413 - Payload Too Large theme={null}
  {
    "success": false,
    "message": "File size exceeds maximum allowed limit"
  }
  ```
</ResponseExample>

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  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
  ```

  ```python Python theme={null}
  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')}")
  ```

  ```javascript JavaScript theme={null}
  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}`);
  }
  ```
</CodeGroup>

## Usage Notes

<Note>
  **File Source**: The `.pictai` file must be exported from the Pictory web application. You can download project files from your Pictory dashboard.
</Note>

<Warning>
  **File Size Limits**: Ensure your template file is within the allowed size limit. Large files with many high-resolution assets may exceed upload limits.
</Warning>

<Tip>
  **Template Variables**: Design your templates with variables (e.g., `{{customer_name}}`, `{{payment_date}}`) to make them reusable across different video instances.
</Tip>

## How to Export a .pictai File

To create a template, you first need to export a project file from the Pictory web app:

1. **Create or Open a Project** in the Pictory web application
2. **Design Your Template** with the desired scenes, text, visuals, and audio
3. **Add Variables** using double curly braces (e.g., `{{variable_name}}`) in text fields
4. **Export the Project** as a `.pictai` file from the project menu
5. **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:

```python theme={null}
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:

```python theme={null}
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:

```javascript theme={null}
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:

```python theme={null}
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:

```python theme={null}
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

1. **Organize Templates**: Keep template files organized by category or purpose
2. **Version Control**: Maintain version history of template files
3. **Naming Convention**: Use descriptive names for template files
4. **Backup**: Keep backups of all template files
5. **Documentation**: Document the purpose and variables of each template

### Template Design

1. **Use Meaningful Variables**: Choose clear, descriptive variable names
2. **Consistent Naming**: Use a consistent naming convention for variables (e.g., `snake_case`)
3. **Default Values**: Provide sensible default values in the template
4. **Test Thoroughly**: Test templates with various variable values before uploading
5. **Optimize Assets**: Keep file sizes reasonable by optimizing images and videos

### Error Handling

1. **Validate Files**: Check file format and size before uploading
2. **Handle Failures**: Implement retry logic for network failures
3. **Log Uploads**: Keep records of uploaded templates
4. **Monitor Limits**: Track upload quotas and limits
5. **Verify Results**: Confirm template creation by checking the response
