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

# Render Storyboard Video

> Render a final video from a storyboard with all scenes, visuals, voice-over, and effects

## Overview

The Render Storyboard Video API generates the final rendered video file from your storyboard configuration. This endpoint processes all scenes, applies voice-over narration, background music, visual effects, and produces a complete video ready for distribution.

<Note>
  This endpoint renders the final video directly. For a preview-first workflow, use the [Create Storyboard Preview API](/api-reference/videos/create-storyboard-preview) to review scenes before rendering.
</Note>

<Tip>
  **Direct Render:** Use this endpoint when you are confident in your content and want to skip the preview step, or when re-rendering a previously approved storyboard.
</Tip>

***

## Render Workflow Options

| Workflow                      | API                                                                          | When to Use                                        |
| ----------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------- |
| **Create Preview**            | [Create Storyboard Preview](/api-reference/videos/create-storyboard-preview) | Generate preview to review scenes before rendering |
| **Render from Preview**       | [Render from Preview](/api-reference/videos/render-from-preview)             | Render preview as-is without modifications         |
| **Render with Modifications** | [Render Video](/api-reference/videos/render-video)                           | Modify preview elements before rendering           |
| **Render Saved Project**      | [Render Project](/api-reference/videos/render-project)                       | Render existing project created in App or via API  |
| **Direct Render**             | **This API**                                                                 | Skip preview, render directly from input           |

***

## Preview vs. Final Render

| Aspect       | Storyboard Preview                            | Final Render             |
| ------------ | --------------------------------------------- | ------------------------ |
| **Purpose**  | Review and validate content                   | Produce final video file |
| **Output**   | Scene thumbnails, metadata, project structure | Full HD video file       |
| **Speed**    | Fast                                          | Slower                   |
| **Cost**     | Lower resource usage                          | Full rendering resources |
| **Editable** | Yes, make changes before render               | Video is final           |
| **Use Case** | Content approval, iteration                   | Final delivery           |

***

## Use Cases

<CardGroup cols={2}>
  <Card title="Direct Video Creation" icon="video">
    Generate final videos directly from text, articles, or presentations
  </Card>

  <Card title="Batch Rendering" icon="layer-group">
    Render multiple videos programmatically at scale
  </Card>

  <Card title="Automated Pipelines" icon="gears">
    Integrate into automated content creation workflows
  </Card>

  <Card title="Re-rendering" icon="arrows-rotate">
    Re-render videos after making adjustments to projects
  </Card>

  <Card title="Template-based Videos" icon="clone">
    Generate videos from templates with variable content
  </Card>

  <Card title="Multi-platform Content" icon="share-nodes">
    Create videos for different platforms with aspect ratios
  </Card>
</CardGroup>

***

## API Endpoint

```http theme={null}
POST https://api.pictory.ai/pictoryapis/v2/video/storyboard/render
```

***

## Request Headers

<ParamField header="Authorization" type="string" required>
  API key for authentication

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

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`
</ParamField>

***

## Request Body Parameters

The request body accepts the same parameters as the [Create Storyboard Preview API](/api-reference/videos/create-storyboard-preview#request-body-parameters). All parameters for video configuration, scenes, voice-over, background music, branding, and destinations are supported.

<ParamField body="videoName" type="string" required>
  Name for your video project (alphanumeric, spaces, underscores, and hyphens only, max 150 characters)
</ParamField>

<ParamField body="videoWidth" type="integer">
  Width of the generated video in pixels. Must be provided together with `videoHeight`.
</ParamField>

<ParamField body="videoHeight" type="integer">
  Height of the generated video in pixels. Must be provided together with `videoWidth`.
</ParamField>

<ParamField body="aspectRatio" type="string">
  Video aspect ratio. Options: `1:1`, `16:9`, `9:16`, `4:5`
</ParamField>

<ParamField body="language" type="string">
  Language of the text content.

  **Allowed values:** `zh`, `nl`, `en`, `fr`, `de`, `hi`, `it`, `ja`, `ko`, `mr`, `pt`, `ru`, `es`, `ta`

  `zh` Chinese, `nl` Dutch, `en` English, `fr` French, `de` German, `hi` Hindi, `it` Italian, `ja` Japanese, `ko` Korean, `mr` Marathi, `pt` Portuguese, `ru` Russian, `es` Spanish, `ta` Tamil
</ParamField>

<ParamField body="saveProject" type="boolean">
  Whether to save the project in your Pictory account for later editing. Default: `false`
</ParamField>

<ParamField body="webhook" type="string">
  URL where the completed video output will be sent via POST request when finished (max 500 characters)
</ParamField>

<ParamField body="webhookInput" type="object">
  Custom data object that will be included in the webhook POST payload when the job completes. Use this to pass through any metadata (e.g., internal IDs, tracking info) that you need in your webhook handler.

  ```json theme={null}
  {
    "webhookInput": {
      "internalId": "abc-123",
      "source": "campaign-builder"
    }
  }
  ```
</ParamField>

<ParamField body="templateId" type="string">
  ID of a template to use. Get from [Get Templates](/api-reference/templates/get-templates) API.
</ParamField>

<ParamField body="variables" type="object">
  Key-value object for template variables. Only applicable when `templateId` is provided.

  ```json theme={null}
  {
    "variables": {
      "headline": "Welcome to Our Product",
      "subheadline": "Discover Amazing Features",
      "ctaText": "Learn More"
    }
  }
  ```
</ParamField>

<ParamField body="brandId" type="string">
  ID of the brand to apply. Get from [Get Video Brands](/api-reference/branding/get-video-brands) API. Cannot be used with `brandName`.
</ParamField>

<ParamField body="brandName" type="string">
  Name of the brand to apply. Cannot be used with `brandId`.
</ParamField>

<ParamField body="smartLayoutName" type="string">
  Name of the smart layout to apply. Get available layouts from [Get Smart Layouts](/api-reference/smartlayouts/get-smart-layouts) API. Cannot be used with `smartLayoutId`.
</ParamField>

<ParamField body="smartLayoutId" type="string">
  ID of the smart layout to apply. Get from [Get Smart Layouts](/api-reference/smartlayouts/get-smart-layouts) API. Cannot be used with `smartLayoutName`.
</ParamField>

<ParamField body="storyboardVersion" type="string">
  <Warning>**Experimental:** This field is currently experimental. In the future, all storyboards will automatically use the latest version, and this field will be ignored. There is no need to remove it from your requests when that happens.</Warning>

  Specifies which storyboard version to use. Set to `v3` to create a latest Pictory storyboard. Omit this field to use the classic storyboard.

  Options:

  * `v3`: Uses the latest Pictory storyboard
  * Omit or any other value: Uses the classic/legacy storyboard
</ParamField>

<ParamField body="subtitleStyleId" type="string">
  ID of a saved text style for subtitles. Get from [Get Text Styles](/api-reference/branding/get-text-styles) API. Cannot be used with `subtitleStyleName`.
</ParamField>

<ParamField body="subtitleStyleName" type="string">
  Name of a saved text style for subtitles. Cannot be used with `subtitleStyleId`.
</ParamField>

<ParamField body="subtitleStyle" type="object">
  Inline subtitle style configuration. See [Create Storyboard Preview - subtitleStyle Object](/api-reference/videos/create-storyboard-preview#subtitlestyle-object).

  ```json theme={null}
  {
    "subtitleStyle": {
      "fontFamily": "Montserrat",
      "fontSize": 48,
      "color": "rgba(255,255,255,1)",
      "backgroundColor": "rgba(0,0,0,0.5)",
      "position": "bottom-center",
      "alignment": "center"
    }
  }
  ```
</ParamField>

<ParamField body="awsConnectionId" type="string">
  AWS connection ID for accessing private S3 assets. Get from [Get AWS Connections](/api-reference/aws-integration/get-aws-connections) API.
</ParamField>

<ParamField body="vimeoConnectionId" type="string">
  Vimeo connection ID for uploading videos directly to Vimeo. Get from [Get Vimeo Connections](/api-reference/vimeo-integration/get-vimeo-connections) API.
</ParamField>

<ParamField body="destinations" type="array">
  Array of destination configurations for uploading the generated video (max 5). See [Create Storyboard Preview - destinations Array](/api-reference/videos/create-storyboard-preview#destinations-array).

  ```json theme={null}
  {
    "destinations": [
      {
        "type": "vimeo",
        "folder_uri": "/users/12345/projects/67890",
        "content_rating": ["safe"],
        "privacy": {
          "view": "unlisted",
          "embed": "public",
          "download": false
        }
      }
    ]
  }
  ```
</ParamField>

<ParamField body="voiceOver" type="object">
  Voice-over configuration for AI narration. See [Create Storyboard Preview - voiceOver Object](/api-reference/videos/create-storyboard-preview#voiceover-object).

  ```json theme={null}
  {
    "voiceOver": {
      "enabled": true,
      "aiVoices": [
        {
          "speaker": "Brian",
          "speed": 100,
          "amplificationLevel": 0
        }
      ]
    }
  }
  ```
</ParamField>

<ParamField body="backgroundMusic" type="object">
  Background music configuration for the video. See [Create Storyboard Preview - backgroundMusic Object](/api-reference/videos/create-storyboard-preview#backgroundmusic-object).

  ```json theme={null}
  {
    "backgroundMusic": {
      "enabled": true,
      "autoMusic": true,
      "volume": 0.5
    }
  }
  ```
</ParamField>

<ParamField body="logo" type="object">
  Logo overlay configuration. See [Create Storyboard Preview - logo Object](/api-reference/videos/create-storyboard-preview#logo-object).

  ```json theme={null}
  {
    "logo": {
      "url": "https://example.com/logo.png",
      "position": "top-right",
      "width": "15%"
    }
  }
  ```
</ParamField>

<ParamField body="scenes" type="array" required>
  Array of scene objects containing the content to convert into video. Required unless using `templateId`. See [Create Storyboard Preview - scenes Array](/api-reference/videos/create-storyboard-preview#scenes-array).

  ```json theme={null}
  {
    "scenes": [
      {
        "story": "Welcome to our product showcase. Discover amazing features.",
        "createSceneOnEndOfSentence": true,
        "highlightKeywords": true,
        "sceneTransition": "fade",
        "background": {
          "visualUrl": "https://example.com/background.mp4",
          "type": "video",
          "settings": {
            "mute": true,
            "loop": true
          }
        }
      }
    ]
  }
  ```
</ParamField>

***

## Response

When the render request is successfully submitted, a job is created and a job ID is returned.

<ResponseField name="success" type="boolean">
  Indicates whether the request was successful
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="jobId" type="string">
    Unique identifier for the render job. Use this to track the job status and retrieve results via the [Get Video Render Job by ID](/api-reference/jobs/get-video-render-job-by-id) endpoint.
  </ResponseField>
</ResponseField>

<ResponseExample>
  ```json 200 - Job Created theme={null}
  {
      "success": true,
      "data": {
          "jobId": "265a7c1a-4985-4058-9208-68114f131a2b"
      }
  }
  ```

  ```json 400 - Bad Request theme={null}
  {
      "code": "INVALID_REQUEST_BODY",
      "message": "Request body validation failed.",
      "fields": [
          {
              "name": "scenes",
              "errors": "scenes is required"
          }
      ]
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
      "message": "Unauthorized"
  }
  ```
</ResponseExample>

## Next Steps

Once you have the `jobId`, poll the [Get Video Render Job by ID](/api-reference/jobs/get-video-render-job-by-id) endpoint to check the render status and retrieve the output URLs when complete. Use a polling interval of 10–30 seconds.

***

## Code Examples

<Tip>
  Replace `YOUR_API_KEY` with your actual API key
</Tip>

### Basic Text to Video Render

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.pictory.ai/pictoryapis/v2/video/storyboard/render \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "videoName": "my_rendered_video",
      "aspectRatio": "16:9",
      "voiceOver": {
        "enabled": true,
        "aiVoices": [{"speaker": "Brian", "speed": 100}]
      },
      "scenes": [
        {
          "story": "Welcome to our company. We create innovative solutions for modern businesses.",
          "createSceneOnEndOfSentence": true
        }
      ]
    }' | python -m json.tool
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.pictory.ai/pictoryapis/v2/video/storyboard/render', {
    method: 'POST',
    headers: {
      'Authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      videoName: 'my_rendered_video',
      aspectRatio: '16:9',
      voiceOver: {
        enabled: true,
        aiVoices: [{ speaker: 'Brian', speed: 100 }]
      },
      scenes: [{
        story: 'Welcome to our company. We create innovative solutions for modern businesses.',
        createSceneOnEndOfSentence: true
      }]
    })
  });

  const data = await response.json();
  console.log('Job ID:', data.data.jobId);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.pictory.ai/pictoryapis/v2/video/storyboard/render',
      headers={
          'Authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'videoName': 'my_rendered_video',
          'aspectRatio': '16:9',
          'voiceOver': {
              'enabled': True,
              'aiVoices': [{'speaker': 'Brian', 'speed': 100}]
          },
          'scenes': [{
              'story': 'Welcome to our company. We create innovative solutions for modern businesses.',
              'createSceneOnEndOfSentence': True
          }]
      }
  )

  data = response.json()
  print('Job ID:', data['data']['jobId'])
  ```

  ```php PHP theme={null}
  <?php

  $url = 'https://api.pictory.ai/pictoryapis/v2/video/storyboard/render';

  $payload = [
      'videoName' => 'my_rendered_video',
      'aspectRatio' => '16:9',
      'voiceOver' => [
          'enabled' => true,
          'aiVoices' => [['speaker' => 'Brian', 'speed' => 100]]
      ],
      'scenes' => [[
          'story' => 'Welcome to our company. We create innovative solutions for modern businesses.',
          'createSceneOnEndOfSentence' => true
      ]]
  ];

  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: YOUR_API_KEY',
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

  $response = curl_exec($ch);
  curl_close($ch);

  $data = json_decode($response, true);
  echo 'Job ID: ' . $data['data']['jobId'] . PHP_EOL;
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io"
      "net/http"
  )

  func main() {
      url := "https://api.pictory.ai/pictoryapis/v2/video/storyboard/render"

      payload := map[string]interface{}{
          "videoName":   "my_rendered_video",
          "aspectRatio": "16:9",
          "voiceOver": map[string]interface{}{
              "enabled": true,
              "aiVoices": []map[string]interface{}{
                  {"speaker": "Brian", "speed": 100},
              },
          },
          "scenes": []map[string]interface{}{
              {
                  "story":                    "Welcome to our company. We create innovative solutions for modern businesses.",
                  "createSceneOnEndOfSentence": true,
              },
          },
      }

      requestBody, _ := json.Marshal(payload)

      req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
      if err != nil {
          panic(err)
      }

      req.Header.Set("Authorization", "YOUR_API_KEY")
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)

      var result map[string]interface{}
      json.Unmarshal(body, &result)

      data := result["data"].(map[string]interface{})
      fmt.Println("Job ID:", data["jobId"])
  }
  ```
</CodeGroup>

### Render with Full Configuration

<CodeGroup>
  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.pictory.ai/pictoryapis/v2/video/storyboard/render', {
    method: 'POST',
    headers: {
      'Authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      videoName: 'complete_video_render',
      aspectRatio: '16:9',
      saveProject: true,
      webhook: 'https://your-server.com/webhook',

      // Branding
      brandName: 'My Brand',

      // Voice-over
      voiceOver: {
        enabled: true,
        aiVoices: [{
          speaker: 'Emma',
          speed: 100,
          amplificationLevel: 0
        }]
      },

      // Background music
      backgroundMusic: {
        enabled: true,
        autoMusic: true,
        volume: 0.3
      },

      // Logo
      logo: {
        url: 'https://example.com/logo.png',
        position: 'top-right',
        width: '15%'
      },

      // Subtitle styling
      subtitleStyle: {
        fontFamily: 'Montserrat',
        fontSize: 48,
        color: 'rgba(255,255,255,1)',
        position: 'bottom-center'
      },

      // Scenes
      scenes: [{
        story: 'Welcome to our company. We create innovative solutions. Join us on this journey.',
        createSceneOnEndOfSentence: true,
        highlightKeywords: true,
        sceneTransition: 'fade'
      }]
    })
  });

  const data = await response.json();
  console.log('Job ID:', data.data.jobId);
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.pictory.ai/pictoryapis/v2/video/storyboard/render',
      headers={
          'Authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'videoName': 'complete_video_render',
          'aspectRatio': '16:9',
          'saveProject': True,
          'webhook': 'https://your-server.com/webhook',

          # Branding
          'brandName': 'My Brand',

          # Voice-over
          'voiceOver': {
              'enabled': True,
              'aiVoices': [{
                  'speaker': 'Emma',
                  'speed': 100,
                  'amplificationLevel': 0
              }]
          },

          # Background music
          'backgroundMusic': {
              'enabled': True,
              'autoMusic': True,
              'volume': 0.3
          },

          # Logo
          'logo': {
              'url': 'https://example.com/logo.png',
              'position': 'top-right',
              'width': '15%'
          },

          # Subtitle styling
          'subtitleStyle': {
              'fontFamily': 'Montserrat',
              'fontSize': 48,
              'color': 'rgba(255,255,255,1)',
              'position': 'bottom-center'
          },

          # Scenes
          'scenes': [{
              'story': 'Welcome to our company. We create innovative solutions. Join us on this journey.',
              'createSceneOnEndOfSentence': True,
              'highlightKeywords': True,
              'sceneTransition': 'fade'
          }]
      }
  )

  data = response.json()
  print('Job ID:', data['data']['jobId'])
  ```

  ```php PHP theme={null}
  <?php

  $url = 'https://api.pictory.ai/pictoryapis/v2/video/storyboard/render';

  $payload = [
      'videoName' => 'complete_video_render',
      'aspectRatio' => '16:9',
      'saveProject' => true,
      'webhook' => 'https://your-server.com/webhook',

      // Branding
      'brandName' => 'My Brand',

      // Voice-over
      'voiceOver' => [
          'enabled' => true,
          'aiVoices' => [[
              'speaker' => 'Emma',
              'speed' => 100,
              'amplificationLevel' => 0
          ]]
      ],

      // Background music
      'backgroundMusic' => [
          'enabled' => true,
          'autoMusic' => true,
          'volume' => 0.3
      ],

      // Logo
      'logo' => [
          'url' => 'https://example.com/logo.png',
          'position' => 'top-right',
          'width' => '15%'
      ],

      // Subtitle styling
      'subtitleStyle' => [
          'fontFamily' => 'Montserrat',
          'fontSize' => 48,
          'color' => 'rgba(255,255,255,1)',
          'position' => 'bottom-center'
      ],

      // Scenes
      'scenes' => [[
          'story' => 'Welcome to our company. We create innovative solutions. Join us on this journey.',
          'createSceneOnEndOfSentence' => true,
          'highlightKeywords' => true,
          'sceneTransition' => 'fade'
      ]]
  ];

  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Authorization: YOUR_API_KEY',
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

  $response = curl_exec($ch);
  curl_close($ch);

  $data = json_decode($response, true);
  echo 'Job ID: ' . $data['data']['jobId'] . PHP_EOL;
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io"
      "net/http"
  )

  func main() {
      url := "https://api.pictory.ai/pictoryapis/v2/video/storyboard/render"

      payload := map[string]interface{}{
          "videoName":   "complete_video_render",
          "aspectRatio": "16:9",
          "saveProject": true,
          "webhook":     "https://your-server.com/webhook",

          // Branding
          "brandName": "My Brand",

          // Voice-over
          "voiceOver": map[string]interface{}{
              "enabled": true,
              "aiVoices": []map[string]interface{}{
                  {
                      "speaker":            "Emma",
                      "speed":              100,
                      "amplificationLevel": 0,
                  },
              },
          },

          // Background music
          "backgroundMusic": map[string]interface{}{
              "enabled":   true,
              "autoMusic": true,
              "volume":    0.3,
          },

          // Logo
          "logo": map[string]interface{}{
              "url":      "https://example.com/logo.png",
              "position": "top-right",
              "width":    "15%",
          },

          // Subtitle styling
          "subtitleStyle": map[string]interface{}{
              "fontFamily": "Montserrat",
              "fontSize":   48,
              "color":      "rgba(255,255,255,1)",
              "position":   "bottom-center",
          },

          // Scenes
          "scenes": []map[string]interface{}{
              {
                  "story":                    "Welcome to our company. We create innovative solutions. Join us on this journey.",
                  "createSceneOnEndOfSentence": true,
                  "highlightKeywords":        true,
                  "sceneTransition":          "fade",
              },
          },
      }

      requestBody, _ := json.Marshal(payload)

      req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
      if err != nil {
          panic(err)
      }

      req.Header.Set("Authorization", "YOUR_API_KEY")
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)

      var result map[string]interface{}
      json.Unmarshal(body, &result)

      data := result["data"].(map[string]interface{})
      fmt.Println("Job ID:", data["jobId"])
  }
  ```
</CodeGroup>

### Poll for Completion

<CodeGroup>
  ```javascript JavaScript theme={null}
  async function waitForVideo(jobId, apiKey) {
    const maxAttempts = 60;
    const pollInterval = 10000; // 10 seconds

    for (let attempt = 0; attempt < maxAttempts; attempt++) {
      const response = await fetch(
        `https://api.pictory.ai/pictoryapis/v1/jobs/${jobId}`,
        { headers: { 'Authorization': apiKey } }
      );

      const data = await response.json();
      const status = data.data.status;

      console.log(`Attempt ${attempt + 1}: Status = ${status}`);

      if (status === 'completed') {
        console.log('Video URL:', data.data.videoURL);
        return data.data;
      }

      if (status === 'failed') {
        throw new Error('Video rendering failed: ' + JSON.stringify(data));
      }

      await new Promise(resolve => setTimeout(resolve, pollInterval));
    }

    throw new Error('Timeout waiting for video to render');
  }

  // Usage
  const jobId = 'your-job-id';
  const result = await waitForVideo(jobId, 'YOUR_API_KEY');
  ```

  ```python Python theme={null}
  import requests
  import time

  def wait_for_video(job_id, api_key, max_attempts=60, poll_interval=10):
      for attempt in range(max_attempts):
          response = requests.get(
              f'https://api.pictory.ai/pictoryapis/v1/jobs/{job_id}',
              headers={'Authorization': api_key}
          )

          data = response.json()
          status = data['data']['status']

          print(f'Attempt {attempt + 1}: Status = {status}')

          if status == 'completed':
              print('Video URL:', data['data']['videoURL'])
              return data['data']

          if status == 'failed':
              raise Exception(f'Video rendering failed: {data}')

          time.sleep(poll_interval)

      raise Exception('Timeout waiting for video to render')

  # Usage
  job_id = 'your-job-id'
  result = wait_for_video(job_id, 'YOUR_API_KEY')
  ```

  ```php PHP theme={null}
  <?php

  function waitForVideo($jobId, $apiKey, $maxAttempts = 60, $pollInterval = 10) {
      for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
          $url = "https://api.pictory.ai/pictoryapis/v1/jobs/{$jobId}";

          $ch = curl_init($url);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_HTTPHEADER, [
              'Authorization: ' . $apiKey
          ]);

          $response = curl_exec($ch);
          curl_close($ch);

          $data = json_decode($response, true);
          $status = $data['data']['status'];

          echo "Attempt " . ($attempt + 1) . ": Status = {$status}\n";

          if ($status === 'completed') {
              echo "Video URL: " . $data['data']['videoURL'] . "\n";
              return $data['data'];
          }

          if ($status === 'failed') {
              throw new Exception('Video rendering failed: ' . json_encode($data));
          }

          sleep($pollInterval);
      }

      throw new Exception('Timeout waiting for video to render');
  }

  // Usage
  $jobId = 'your-job-id';
  $result = waitForVideo($jobId, 'YOUR_API_KEY');
  ?>
  ```

  ```go Go theme={null}
  package main

  import (
      "encoding/json"
      "fmt"
      "io"
      "net/http"
      "time"
  )

  type JobResponse struct {
      Data struct {
          Status   string `json:"status"`
          VideoURL string `json:"videoURL"`
      } `json:"data"`
  }

  func waitForVideo(jobID, apiKey string, maxAttempts int, pollInterval time.Duration) (*JobResponse, error) {
      for attempt := 0; attempt < maxAttempts; attempt++ {
          url := fmt.Sprintf("https://api.pictory.ai/pictoryapis/v1/jobs/%s", jobID)

          req, err := http.NewRequest("GET", url, nil)
          if err != nil {
              return nil, err
          }

          req.Header.Set("Authorization", apiKey)

          client := &http.Client{}
          resp, err := client.Do(req)
          if err != nil {
              return nil, err
          }

          body, _ := io.ReadAll(resp.Body)
          resp.Body.Close()

          var result JobResponse
          json.Unmarshal(body, &result)

          status := result.Data.Status
          fmt.Printf("Attempt %d: Status = %s\n", attempt+1, status)

          if status == "completed" {
              fmt.Printf("Video URL: %s\n", result.Data.VideoURL)
              return &result, nil
          }

          if status == "failed" {
              return nil, fmt.Errorf("video rendering failed: %s", string(body))
          }

          time.Sleep(pollInterval)
      }

      return nil, fmt.Errorf("timeout waiting for video to render")
  }

  func main() {
      jobID := "your-job-id"
      result, err := waitForVideo(jobID, "YOUR_API_KEY", 60, 10*time.Second)
      if err != nil {
          panic(err)
      }

      fmt.Printf("Video ready: %s\n", result.Data.VideoURL)
  }
  ```
</CodeGroup>

***

## Related APIs

<CardGroup cols={2}>
  <Card title="Create Storyboard Preview" icon="eye" href="/api-reference/videos/create-storyboard-preview">
    Preview storyboard before rendering
  </Card>

  <Card title="Get Render Job Status" icon="spinner" href="/api-reference/jobs/get-video-render-job-by-id">
    Monitor rendering progress
  </Card>

  <Card title="Get Projects" icon="folder" href="/api-reference/projects/get-projects">
    List saved video projects
  </Card>

  <Card title="Get Voiceover Tracks" icon="microphone" href="/api-reference/voiceovers/get-voiceover-tracks">
    List available AI voices
  </Card>
</CardGroup>
