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

# Generate Video

> Generate an AI video from a text prompt using a selection of AI video models

## Overview

The Generate Video API creates an AI-generated video based on a text prompt. You can choose from multiple AI video models, specify an aspect ratio and duration, and optionally provide a first frame image, a video to extend, or reference images to guide the output. The API returns a job ID that you can use to poll for the result once the video generation is complete.

<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}
POST https://api.pictory.ai/pictoryapis/v1/aistudio/videos
```

***

## Request 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 `application/json`
</ParamField>

***

## Request Body

<ParamField body="prompt" type="string" required>
  A text description of the video you want to generate. The prompt must be between 5 and 5,000 characters.

  **Example:** `"A drone flying over a lush green forest with sunlight filtering through the canopy"`
</ParamField>

<ParamField body="model" type="string">
  The AI model to use for video generation. Each model offers different quality levels, durations, and aspect ratios. Defaults to `pixverse5.5` if not specified.

  **Supported models:** `veo3.1`, `veo3.1_fast`, `pixverse5.5`

  **Model Capabilities and Pricing:**

  | Model         | Supported Aspect Ratios             | Supported Durations | AI Credits per Second |
  | ------------- | ----------------------------------- | ------------------- | --------------------- |
  | `veo3.1`      | `16:9`, `9:16`                      | `4s`, `6s`, `8s`    | 20                    |
  | `veo3.1_fast` | `16:9`, `9:16`                      | `4s`, `6s`, `8s`    | 10                    |
  | `pixverse5.5` | `16:9`, `9:16`, `1:1`, `3:4`, `4:3` | `5s`, `8s`, `10s`   | 1.6                   |
</ParamField>

<ParamField body="aspectRatio" type="string">
  The aspect ratio for the generated video. The available values depend on the selected model. Defaults to the first supported aspect ratio of the chosen model. Refer to the model table above for supported aspect ratios per model.
</ParamField>

<ParamField body="duration" type="string">
  The duration of the generated video. The available values depend on the selected model. Defaults to the first supported duration of the chosen model. Refer to the model table above for supported durations per model.
</ParamField>

<ParamField body="firstFrameImageUrl" type="string">
  An optional URL of an image to use as the first frame of the video. This guides the visual starting point for the generation. The URL must be a valid, publicly accessible URI.

  <Warning>
    This parameter cannot be used together with `extendVideoUrl` or `referenceImageUrls`.
  </Warning>
</ParamField>

<ParamField body="extendVideoUrl" type="string">
  An optional URL of an existing video to extend. The AI model will generate additional content that continues from the end of the provided video. The URL must be a valid, publicly accessible URI.

  <Warning>
    This parameter cannot be used together with `firstFrameImageUrl`.
  </Warning>
</ParamField>

<ParamField body="referenceImageUrls" type="array">
  An optional array of image URLs (1 to 3) to use as visual references for the generated video. The AI model will use these images to influence the style and content of the output. Each URL must be a valid, publicly accessible URI.

  <Warning>
    This parameter cannot be used together with `firstFrameImageUrl` or `extendVideoUrl`.
  </Warning>
</ParamField>

<ParamField body="webhook" type="string">
  An optional webhook URL that will receive a notification when the video generation job completes. The URL must be a valid URI.
</ParamField>

***

## Response

### Success Response (200)

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

<ResponseField name="data" type="object">
  <ResponseField name="jobId" type="string">
    The unique identifier (UUID) of the video generation job. Use this ID to poll for the result using the [Get Video Generation Job](/api-reference/ai-studio/get-video-job) endpoint.
  </ResponseField>
</ResponseField>

### Response Examples

<ResponseExample>
  ```json 200 - Success theme={null}
  {
      "success": true,
      "data": {
          "jobId": "4a09edf9-d071-4847-bda5-8dea913d80fe"
      }
  }
  ```

  ```json 400 - Validation Error theme={null}
  {
      "code": "INVALID_REQUEST_BODY",
      "message": "Request body validation failed.",
      "fields": [
          {
              "field": "prompt",
              "message": "\"prompt\" is required"
          }
      ]
  }
  ```

  ```json 400 - Invalid Parameter Combination theme={null}
  {
      "code": "INVALID_REQUEST_BODY",
      "message": "Request body validation failed.",
      "fields": [
          {
              "field": "extendVideoUrl",
              "message": "\"extendVideoUrl\" is not allowed"
          }
      ]
  }
  ```

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

  ```json 500 - Internal Server Error theme={null}
  {
      "message": "Internal Server Error"
  }
  ```
</ResponseExample>

***

## Status Codes

| Status Code | Description                                                                                                                                           |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **200**     | Job created successfully. Use the returned `jobId` to poll for the result.                                                                            |
| **400**     | Invalid request body. Check the `fields` array for specific validation errors. This also occurs when mutually exclusive parameters are used together. |
| **401**     | Unauthorized. The API key in the `Authorization` header is missing or invalid.                                                                        |
| **500**     | Internal server error. Retry the request after a brief delay.                                                                                         |

***

## Parameter Exclusivity

The `firstFrameImageUrl`, `extendVideoUrl`, and `referenceImageUrls` parameters are mutually exclusive. You may use only one of these in a single request. Providing more than one will result in a `400` validation error.

| Parameter            | Can be combined with                                         |
| -------------------- | ------------------------------------------------------------ |
| `firstFrameImageUrl` | `prompt`, `model`, `aspectRatio`, `duration`, `webhook` only |
| `extendVideoUrl`     | `prompt`, `model`, `aspectRatio`, `duration`, `webhook` only |
| `referenceImageUrls` | `prompt`, `model`, `aspectRatio`, `duration`, `webhook` only |

***

## Code Examples

<Tip>
  Replace `YOUR_API_KEY` with your actual API key from the [API Access page](https://app.pictory.ai/api-access).
</Tip>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.pictory.ai/pictoryapis/v1/aistudio/videos' \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --data '{
      "prompt": "A drone flying over a lush green forest with sunlight filtering through the canopy",
      "model": "pixverse5.5",
      "aspectRatio": "16:9",
      "duration": "8s"
    }'
  ```

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

  url = "https://api.pictory.ai/pictoryapis/v1/aistudio/videos"
  headers = {
      "Authorization": "YOUR_API_KEY",
      "Content-Type": "application/json"
  }
  payload = {
      "prompt": "A drone flying over a lush green forest with sunlight filtering through the canopy",
      "model": "pixverse5.5",
      "aspectRatio": "16:9",
      "duration": "8s"
  }

  response = requests.post(url, json=payload, headers=headers)
  data = response.json()

  if data.get("success"):
      job_id = data["data"]["jobId"]
      print(f"Video generation job created: {job_id}")
  else:
      print(f"Error: {data}")
  ```

  ```javascript JavaScript theme={null}
  const url = 'https://api.pictory.ai/pictoryapis/v1/aistudio/videos';

  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      prompt: 'A drone flying over a lush green forest with sunlight filtering through the canopy',
      model: 'pixverse5.5',
      aspectRatio: '16:9',
      duration: '8s'
    })
  });

  const data = await response.json();

  if (data.success) {
    console.log(`Video generation job created: ${data.data.jobId}`);
  } else {
    console.log('Error:', data);
  }
  ```

  ```php PHP theme={null}
  <?php
  $url = "https://api.pictory.ai/pictoryapis/v1/aistudio/videos";
  $payload = json_encode([
      "prompt" => "A drone flying over a lush green forest with sunlight filtering through the canopy",
      "model" => "pixverse5.5",
      "aspectRatio" => "16:9",
      "duration" => "8s"
  ]);

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

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

  $data = json_decode($response, true);

  if ($data['success']) {
      echo "Video generation job created: " . $data['data']['jobId'] . "\n";
  } else {
      echo "Error: " . json_encode($data) . "\n";
  }
  ?>
  ```

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

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

  func main() {
      url := "https://api.pictory.ai/pictoryapis/v1/aistudio/videos"

      payload := map[string]string{
          "prompt":      "A drone flying over a lush green forest with sunlight filtering through the canopy",
          "model":       "pixverse5.5",
          "aspectRatio": "16:9",
          "duration":    "8s",
      }
      jsonPayload, _ := json.Marshal(payload)

      req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonPayload))
      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 {
          fmt.Println("Error:", err)
          return
      }
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)
      var data map[string]interface{}
      json.Unmarshal(body, &data)

      if success, ok := data["success"].(bool); ok && success {
          jobData := data["data"].(map[string]interface{})
          fmt.Printf("Video generation job created: %s\n", jobData["jobId"])
      } else {
          fmt.Println("Error:", string(body))
      }
  }
  ```
</CodeGroup>

***

## Next Steps

After receiving the `jobId`, poll for the video generation result using the [Get Video Generation Job](/api-reference/ai-studio/get-video-job) endpoint. Use a polling interval of **10–30 seconds** to check the job status.
