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

# Get Storyboard Preview Job by ID

> Retrieve the status and results of a storyboard preview job

## Overview

This endpoint retrieves the current status and results of a storyboard preview job using its unique job ID. While processing is in progress, it returns the current job status. Once the job completes, it returns the full storyboard preview data, including render parameters, the processed storyboard, and the preview URL.

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

***

## API Endpoint

```http theme={null}
GET https://api.pictory.ai/pictoryapis/v1/jobs/{jobid}
```

***

## Request Parameters

### Path Parameters

<ParamField path="jobid" type="uuid" required>
  The unique identifier (UUID) of the storyboard preview job. This value is the `jobId` returned by the [Create Storyboard Preview](/api-reference/videos/create-storyboard-preview) endpoint.

  **Example:** `"a1d36612-326d-4b81-aece-411f8aed4c70"`
</ParamField>

### Headers

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

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

***

## Response

### In-Progress Response

Returned while the storyboard preview is still being generated:

<ResponseField name="job_id" type="string">
  The unique identifier of the storyboard preview job
</ResponseField>

<ResponseField name="success" type="boolean">
  `true` while the job is processing
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="status" type="string">
    `"in-progress"`: the storyboard preview is still being generated
  </ResponseField>
</ResponseField>

### Failed Response

Returned when the storyboard preview job has failed during processing:

<ResponseField name="job_id" type="string">
  The unique identifier of the storyboard preview job
</ResponseField>

<ResponseField name="success" type="boolean">
  `false` when the job has failed
</ResponseField>

<ResponseField name="data" type="object">
  <ResponseField name="status" type="string">
    `"failed"`: the storyboard preview generation has failed
  </ResponseField>

  <ResponseField name="error_code" type="string">
    Error code identifying the failure type (e.g., `"TEXT_TO_VIDEO_FAILED"`)
  </ResponseField>

  <ResponseField name="error_message" type="string">
    Descriptive message explaining the cause of the failure
  </ResponseField>
</ResponseField>

### Completed Response

Returned when the storyboard preview has been successfully generated. The response contains the full preview data:

<ResponseField name="job_id" type="string">
  The unique identifier of the storyboard preview job
</ResponseField>

<ResponseField name="success" type="boolean">
  `true` when the job has completed successfully
</ResponseField>

<ResponseField name="data" type="object">
  Contains the complete storyboard preview results.

  <ResponseField name="status" type="string">
    `"completed"`: the storyboard preview has been generated successfully
  </ResponseField>

  <Expandable title="renderParams">
    <ResponseField name="renderParams" type="object">
      The rendering data used for previewing and rendering videos. This object contains the complete scene composition, including output settings, audio elements, background visuals, and text overlays.

      <ResponseField name="output" type="object">
        Video output configuration

        <ResponseField name="width" type="integer">
          Video width in pixels (e.g., `1920`)
        </ResponseField>

        <ResponseField name="height" type="integer">
          Video height in pixels (e.g., `1080`)
        </ResponseField>

        <ResponseField name="format" type="string">
          Output format (e.g., `"mp4"`)
        </ResponseField>

        <ResponseField name="name" type="string">
          Output file name
        </ResponseField>

        <ResponseField name="title" type="string">
          Video title
        </ResponseField>
      </ResponseField>

      <ResponseField name="elements" type="array">
        Array of video elements including audio tracks (voice-over, background music), background visuals (videos, images, solid colors), and text overlays (scene text, titles). Each element includes `startTime`, `duration`, `elementType`, and type-specific properties.
      </ResponseField>

      <ResponseField name="sceneMarkers" type="array">
        Array of scene marker objects that define scene boundaries.

        Each marker contains:

        * `time` (number): Scene duration in seconds
        * `showSceneNumber` (string): Scene label (e.g., `"Scene 1"`)
        * `uuid` (string): Unique scene identifier
        * `startTime` (number): Scene start time in seconds
      </ResponseField>

      <ResponseField name="subtitles" type="array">
        Array of subtitle objects with timing information.

        Each subtitle contains:

        * `subtitle` (string): The subtitle text
        * `start` (number): Start time in seconds
        * `end` (number): End time in seconds
      </ResponseField>

      <ResponseField name="projectId" type="string">
        The project ID (matches the job ID)
      </ResponseField>
    </ResponseField>
  </Expandable>

  <Expandable title="storyboard">
    <ResponseField name="storyboard" type="object">
      The processed input storyboard. This is the fully resolved version of the original storyboard request, with all scenes broken down, voice-over URLs generated, and visual selections applied.

      <ResponseField name="videoName" type="string">
        Name of the video project
      </ResponseField>

      <ResponseField name="webhook" type="string">
        The webhook URL configured for the job
      </ResponseField>

      <ResponseField name="webhookInput" type="object">
        Custom data passed through from the original request
      </ResponseField>

      <ResponseField name="smartLayoutName" type="string">
        The smart layout applied to the video
      </ResponseField>

      <ResponseField name="voiceOver" type="object">
        Voice-over configuration
      </ResponseField>

      <ResponseField name="backgroundMusic" type="object">
        Background music configuration, including `enabled`, `volume`, `autoMusic`, and `musicUrl`
      </ResponseField>

      <ResponseField name="scenes" type="array">
        Array of processed scene objects. Each scene contains:

        * `story` (string): Scene text with keyword highlights in `<strong>` tags
        * `voiceOver` (object): Voice-over configuration with the generated audio URL and timing clips
        * `backgroundMusic` (object): Per-scene music settings
        * `background` (object): Visual background with `visualUrl`, `type`, and settings
      </ResponseField>

      <ResponseField name="language" type="string">
        Language code (e.g., `"en"`)
      </ResponseField>
    </ResponseField>
  </Expandable>

  <ResponseField name="previewUrl" type="string">
    URL to view the storyboard preview in a browser. This URL can also be embedded in an iframe for app integrations. Refer to the [Embed Preview Player](/integrations/storyboard-video-preview/embed-preview-player) guide for details.
  </ResponseField>

  <ResponseField name="projectUrl" type="string">
    URL to open the saved project in the [Pictory web app](https://app.pictory.ai). Present only when `saveProject` was set to `true` in the storyboard request.
  </ResponseField>

  <ResponseField name="projectId" type="string">
    Unique identifier of the saved project. Use this value with the [Render Project](/api-reference/videos/render-project) or [Get Project by ID](/api-reference/projects/get-project-by-id) APIs. Present only when `saveProject` was set to `true` in the storyboard request.
  </ResponseField>

  <ResponseField name="aiCreditsUsed" type="number">
    Total AI credits consumed for generating AI visuals (images and video clips) in this storyboard. Present only when the storyboard includes scenes with `aiVisual` configuration. The value is the sum of credits used across all AI-generated scenes.
  </ResponseField>
</ResponseField>

### Response Examples

<ResponseExample>
  ```json 200 - In Progress theme={null}
  {
      "job_id": "a1d36612-326d-4b81-aece-411f8aed4c70",
      "success": true,
      "data": {
          "status": "in-progress"
      }
  }
  ```

  ```json 200 - Completed (abbreviated) theme={null}
  {
      "job_id": "a1d36612-326d-4b81-aece-411f8aed4c70",
      "success": true,
      "data": {
          "status": "completed",
          "renderParams": {
              "output": {
                  "width": 1920,
                  "height": 1080,
                  "format": "mp4",
                  "name": "demo_text_to_video.mp4",
                  "title": "demo_text_to_video",
                  "description": "",
                  "frameRendererVersion": "v3"
              },
              "elements": [
                  {
                      "type": "audio",
                      "id": "voiceOver",
                      "elementType": "audioElement",
                      "url": "https://audios-prod.pictorycontent.com/polly/production/projects/.../voiceover.mp3",
                      "segments": [
                          {
                              "startTime": 0,
                              "duration": 7.5,
                              "volume": 1,
                              "audioTime": 0
                          }
                      ],
                      "startTime": 0,
                      "duration": 100000
                  },
                  {
                      "type": "audio",
                      "id": "bgMusic",
                      "elementType": "audioElement",
                      "fade": true,
                      "url": "https://tracks.melod.ie/track_versions/.../music.mp3",
                      "segments": [
                          {
                              "startTime": 0,
                              "duration": 7.5,
                              "volume": 0.1,
                              "audioTime": 0
                          }
                      ],
                      "startTime": 0,
                      "duration": 100000
                  },
                  {
                      "id": "backgroundElement_...",
                      "elementType": "backgroundElement",
                      "type": "video",
                      "url": "https://media.gettyimages.com/id/.../video.mp4",
                      "backgroundColor": "rgba(0, 0, 0, 1)",
                      "width": "100%",
                      "objectMode": "cover",
                      "loop": true,
                      "mute": true,
                      "startTime": 0,
                      "duration": 7.5,
                      "visualType": "video",
                      "library": "getty"
                  },
                  {
                      "fontFamily": "Space Grotesk",
                      "fontSize": "48",
                      "fontColor": "rgb(255,255,255)",
                      "textAlign": "center",
                      "startTime": 0,
                      "duration": 7.5,
                      "id": "...",
                      "elementType": "layerItem",
                      "type": "text",
                      "text": "AI's Impact on Educators and Creators",
                      "width": "90.00%",
                      "preset": "center-center"
                  }
              ],
              "sceneMarkers": [
                  {
                      "time": 7.5,
                      "showSceneNumber": "Scene 1",
                      "uuid": "202603261544455263c22b912026443bea93884eecfd4fd0c",
                      "startTime": 0
                  },
                  {
                      "time": 10.5,
                      "showSceneNumber": "Scene 2",
                      "uuid": "202603261544465266e15765260d944fb917c28bda80a01aa",
                      "startTime": 7.5
                  }
              ],
              "subtitles": [
                  {
                      "subtitle": "AI is poised to significantly impact educators and course creators on social media.",
                      "start": 0,
                      "end": 7.5
                  },
                  {
                      "subtitle": "By automating tasks like content generation, visual design, and video editing, AI will save time and enhance consistency.",
                      "start": 7.5,
                      "end": 18
                  }
              ],
              "projectId": "a1d36612-326d-4b81-aece-411f8aed4c70",
              "projectAuthorId": "Google_113965628153287895479"
          },
          "storyboard": {
              "videoName": "demo_text_to_video",
              "webhook": "https://webhook.site/your-webhook-id",
              "webhookInput": {
                  "aiVoice": "Brian"
              },
              "smartLayoutName": "Wanderlust",
              "voiceOver": {
                  "enabled": true
              },
              "backgroundMusic": {
                  "enabled": true,
                  "volume": 0.1,
                  "autoMusic": false,
                  "musicUrl": "https://tracks.melod.ie/track_versions/.../music.mp3"
              },
              "scenes": [
                  {
                      "story": "<strong>AI</strong> is poised to significantly <strong>impact</strong> <strong>educators</strong> and <strong>course creators</strong> on <strong>social media</strong>.",
                      "voiceOver": {
                          "enabled": true,
                          "externalVoice": {
                              "voiceUrl": "https://audios-prod.pictorycontent.com/polly/production/projects/.../voiceover.mp3",
                              "clips": [
                                  {
                                      "start": 0,
                                      "end": 7.535
                                  }
                              ],
                              "amplificationLevel": 0
                          }
                      },
                      "backgroundMusic": {
                          "enabled": true
                      },
                      "background": {
                          "visualUrl": "https://media.gettyimages.com/id/.../video.mp4",
                          "type": "video",
                          "settings": {
                              "mute": true,
                              "loop": true
                          }
                      }
                  }
              ],
              "language": "en"
          },
          "previewUrl": "https://video.pictory.ai/v2/preview/a1d36612-326d-4b81-aece-411f8aed4c70?mode=player",
          "projectUrl": "https://app.pictory.ai/story/20260326192215799c0a92885a9db478594c3840411873b6a",
          "projectId": "20260326192215799c0a92885a9db478594c3840411873b6a",
          "aiCreditsUsed": 24
      }
  }
  ```

  <Note>
    The `projectUrl` and `projectId` fields are present only when `saveProject` was set to `true` in the original [Create Storyboard Preview](/api-reference/videos/create-storyboard-preview) request.
  </Note>

  ```json 200 - Failed theme={null}
  {
      "job_id": "0bb0116b-d476-4b60-85ac-ce40ed711991",
      "success": false,
      "data": {
          "status": "failed",
          "error_code": "TEXT_TO_VIDEO_FAILED",
          "error_message": "The AI voice speaker [Timm] is invalid and is not supported. Please provide valid AI voice speaker."
      }
  }
  ```

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

  ```json 200 - Invalid Job ID theme={null}
  {
      "id": "a1d36612-326d-4b81-aece-411f8aed4c71",
      "success": false,
      "data": {
          "error_code": "5000",
          "error_message": "JOB_NOT_FOUND"
      }
  }
  ```
</ResponseExample>

***

## Key Response Fields

| Field           | Description                                                                                                                                                                                                                                                                                                                                                                        |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `renderParams`  | The rendering data for the video. To customize the video, modify this data and submit it to the [Render Video](/api-reference/videos/render-video) API. To update the preview with changes, save the modified data using the [Update Storyboard Elements](/api-reference/video-storyboard/update-storyboard-elements) API. After saving, the preview URL will reflect the updates. |
| `storyboard`    | The processed input storyboard with all scenes resolved. Use this object to submit a new storyboard request with modifications. Re-submissions process faster because the scenes, voices, and visuals have already been resolved.                                                                                                                                                  |
| `previewUrl`    | URL to view the storyboard preview. Open in a browser or embed in an iframe. Refer to the [Embed Preview Player](/integrations/storyboard-video-preview/embed-preview-player) guide for integration details.                                                                                                                                                                       |
| `projectUrl`    | URL to open the saved project in the [Pictory web app](https://app.pictory.ai). Present only when `saveProject: true`.                                                                                                                                                                                                                                                             |
| `projectId`     | Unique identifier of the saved project. Use with the [Render Project](/api-reference/videos/render-project) or [Get Project by ID](/api-reference/projects/get-project-by-id) APIs. Present only when `saveProject: true`.                                                                                                                                                         |
| `aiCreditsUsed` | Total AI credits consumed for generating AI visuals (images and video clips). Present only when the storyboard includes scenes with `aiVisual` configuration.                                                                                                                                                                                                                      |

***

## Code Examples

<Tip>
  Replace `YOUR_API_KEY` with your actual API key and use the `jobId` returned from the [Create Storyboard Preview](/api-reference/videos/create-storyboard-preview) endpoint.
</Tip>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://api.pictory.ai/pictoryapis/v1/jobs/a1d36612-326d-4b81-aece-411f8aed4c70' \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'accept: application/json' | python -m json.tool
  ```

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

  def poll_storyboard_job(api_key, job_id, max_wait=600, poll_interval=15):
      """
      Poll for storyboard preview job completion.

      Args:
          api_key: Your Pictory API key
          job_id: The storyboard preview job ID
          max_wait: Maximum wait time in seconds (default 10 minutes)
          poll_interval: Polling interval in seconds (default 15 seconds)
      """
      url = f"https://api.pictory.ai/pictoryapis/v1/jobs/{job_id}"
      headers = {
          "Authorization": api_key,
          "accept": "application/json"
      }

      start_time = time.time()

      while time.time() - start_time < max_wait:
          response = requests.get(url, headers=headers)
          data = response.json()

          if not data.get("success"):
              print("Job failed")
              return data

          status = data.get("data", {}).get("status")

          if status == "in-progress":
              print(f"Storyboard generation in progress... (elapsed: {int(time.time() - start_time)}s)")
              time.sleep(poll_interval)
              continue

          if status == "completed":
              job_data = data["data"]
              print("Storyboard preview ready!")
              print(f"Preview URL: {job_data.get('previewUrl')}")
              print(f"Scenes: {len(job_data.get('storyboard', {}).get('scenes', []))}")
              return data

          # Unknown status
          print(f"Unexpected status: {status}")
          return data

      print("Timeout waiting for storyboard preview")
      return None

  # Usage
  result = poll_storyboard_job("YOUR_API_KEY", "a1d36612-326d-4b81-aece-411f8aed4c70")

  if result and result.get("success"):
      data = result["data"]

      # Access the preview URL
      preview_url = data.get("previewUrl")
      print(f"Preview: {preview_url}")

      # Access renderParams for customization
      render_params = data.get("renderParams")

      # Access processed storyboard for re-submission
      storyboard = data.get("storyboard")
  ```

  ```javascript JavaScript theme={null}
  const jobId = 'a1d36612-326d-4b81-aece-411f8aed4c70';

  async function pollStoryboardJob(apiKey, jobId, maxWait = 600000, pollInterval = 15000) {
    const url = `https://api.pictory.ai/pictoryapis/v1/jobs/${jobId}`;
    const startTime = Date.now();

    while (Date.now() - startTime < maxWait) {
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Authorization': apiKey,
          'accept': 'application/json'
        }
      });

      const data = await response.json();

      if (!data.success) {
        console.log('Job failed');
        return data;
      }

      const status = data.data?.status;

      if (status === 'in-progress') {
        console.log(`Storyboard generation in progress... (${Math.round((Date.now() - startTime) / 1000)}s)`);
        await new Promise(resolve => setTimeout(resolve, pollInterval));
        continue;
      }

      if (status === 'completed') {
        console.log('Storyboard preview ready!');
        console.log(`Preview URL: ${data.data.previewUrl}`);
        console.log(`Scenes: ${data.data.storyboard?.scenes?.length}`);
        return data;
      }

      console.log(`Unexpected status: ${status}`);
      return data;
    }

    console.log('Timeout waiting for storyboard preview');
    return null;
  }

  // Usage
  const result = await pollStoryboardJob('YOUR_API_KEY', jobId);

  if (result?.success) {
    const { previewUrl, renderParams, storyboard } = result.data;
    console.log(`Preview: ${previewUrl}`);
  }
  ```

  ```php PHP theme={null}
  <?php
  function pollStoryboardJob($apiKey, $jobId, $maxWait = 600, $pollInterval = 15) {
      $url = "https://api.pictory.ai/pictoryapis/v1/jobs/{$jobId}";
      $startTime = time();

      while (time() - $startTime < $maxWait) {
          $ch = curl_init($url);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_HTTPHEADER, [
              'Authorization: ' . $apiKey,
              'accept: application/json'
          ]);

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

          $data = json_decode($response, true);

          if (!$data['success']) {
              echo "Job failed\n";
              return $data;
          }

          $status = $data['data']['status'] ?? null;

          if ($status === 'in-progress') {
              $elapsed = time() - $startTime;
              echo "Storyboard generation in progress... ({$elapsed}s)\n";
              sleep($pollInterval);
              continue;
          }

          if ($status === 'completed') {
              echo "Storyboard preview ready!\n";
              echo "Preview URL: " . ($data['data']['previewUrl'] ?? '') . "\n";
              echo "Scenes: " . count($data['data']['storyboard']['scenes'] ?? []) . "\n";
              return $data;
          }

          echo "Unexpected status: {$status}\n";
          return $data;
      }

      echo "Timeout waiting for storyboard preview\n";
      return null;
  }

  // Usage
  $result = pollStoryboardJob('YOUR_API_KEY', 'a1d36612-326d-4b81-aece-411f8aed4c70');

  if ($result && $result['success']) {
      $previewUrl = $result['data']['previewUrl'] ?? '';
      echo "Preview: {$previewUrl}\n";
  }
  ?>
  ```

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

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

  func pollStoryboardJob(apiKey, jobID string, maxWait, pollInterval time.Duration) (map[string]interface{}, error) {
      url := fmt.Sprintf("https://api.pictory.ai/pictoryapis/v1/jobs/%s", jobID)
      startTime := time.Now()

      for time.Since(startTime) < maxWait {
          req, _ := http.NewRequest("GET", url, nil)
          req.Header.Set("Authorization", apiKey)
          req.Header.Set("accept", "application/json")

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

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

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

          success, _ := data["success"].(bool)
          if !success {
              fmt.Println("Job failed")
              return data, nil
          }

          jobData, _ := data["data"].(map[string]interface{})
          status, _ := jobData["status"].(string)

          if status == "in-progress" {
              elapsed := int(time.Since(startTime).Seconds())
              fmt.Printf("Storyboard generation in progress... (%ds)\n", elapsed)
              time.Sleep(pollInterval)
              continue
          }

          if status == "completed" {
              fmt.Println("Storyboard preview ready!")
              if previewUrl, ok := jobData["previewUrl"].(string); ok {
                  fmt.Printf("Preview URL: %s\n", previewUrl)
              }
              return data, nil
          }

          fmt.Printf("Unexpected status: %s\n", status)
          return data, nil
      }

      return nil, fmt.Errorf("timeout waiting for storyboard preview")
  }

  func main() {
      result, err := pollStoryboardJob(
          "YOUR_API_KEY",
          "a1d36612-326d-4b81-aece-411f8aed4c70",
          10*time.Minute,
          15*time.Second,
      )
      if err != nil {
          fmt.Println("Error:", err)
          return
      }

      if success, ok := result["success"].(bool); ok && success {
          data := result["data"].(map[string]interface{})
          if previewUrl, ok := data["previewUrl"].(string); ok {
              fmt.Printf("Preview: %s\n", previewUrl)
          }
      }
  }
  ```
</CodeGroup>

***

## Working with the Completed Response

### Customizing and Rendering the Video

After the storyboard preview is ready, the following options are available:

<Steps>
  <Step title="Review the Preview">
    Open the `previewUrl` in a browser to review the storyboard preview, including all scenes, visuals, and text overlays.
  </Step>

  <Step title="Update Elements (Optional)">
    To modify scene visuals, text, or other elements, update the `renderParams.elements` data and save it using the [Update Storyboard Elements](/api-reference/video-storyboard/update-storyboard-elements) API. The preview URL will reflect the saved changes.
  </Step>

  <Step title="Render the Final Video">
    Submit the `renderParams` data (modified or as-is) to the [Render Video](/api-reference/videos/render-video) API to produce the final rendered video file.
  </Step>
</Steps>

### Re-submitting a Modified Storyboard

To change the original storyboard structure (for example, different text, a different voice, or different scenes), use the `storyboard` object from the completed response as the request body for a new [Create Storyboard Preview](/api-reference/videos/create-storyboard-preview) request. This approach processes faster because the scenes, voice-over audio, and visual selections have already been resolved.

***

## Polling Best Practices

<Warning>
  Use a polling interval of **10–30 seconds** when checking job status. Polling too frequently may result in rate limiting.
</Warning>

1. **Use webhooks when possible.** Configure a `webhook` URL in the storyboard request to receive automatic notification when the job completes, rather than polling.

2. **Implement timeouts.** Set a maximum wait time. Storyboard previews typically complete within a few minutes, depending on the number of scenes and voice-over generation requirements.

3. **Cache results.** Once a storyboard job completes, store the `renderParams` and `storyboard` data locally. Completed job data may be cleaned after a retention period.
