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

# Veo 3.1

> Text/image-to-video, audio, narrative control

<CardGroup cols={1}>
  <Card title="Try Veo 3.1 in the Workbench" icon="flask" href="https://www.oxen.ai/ai/workbench?model=google-veo-3-1">
    Run this model interactively, tune parameters, and compare outputs.
  </Card>
</CardGroup>

**Model ID:** `google-veo-3-1`

Veo 3.1 is Google's video generation model. It excels at generating high-fidelity videos with native synchronized audio, including dialogue, sound effects, and ambient noise, along with improved narrative control and scene consistency over prior versions.

Some other noteworthy features of Veo 3.1 include image-to-video animation from a first-frame image, strong prompt adherence, and legible on-screen text.

| Metric             | Value   |
| ------------------ | ------- |
| Parameter Count    | Unknown |
| Mixture of Experts | Unknown |
| Context Length     | Unknown |
| Multilingual       | No      |
| Quantized\*        | Unknown |

\**Quantization is specific to the inference provider and the model may be offered with different quantization levels by other providers.*

## Example request

<Tip>
  Use the [Workbench](https://www.oxen.ai/ai/workbench?model=google-veo-3-1) as a request builder: configure parameters for this model in the UI, then open the **API** tab to copy the exact cURL or Python call.
</Tip>

<Tabs>
  <Tab title="Sync">
    This blocks until the video is ready (typically 5-15 minutes). Prefer **Async** or **Async with SSE** for anything beyond quick experimentation.

    See the [video generation reference](/inference-api/reference/video_generation) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/videos/generate \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>"
          }'
          ```

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

          response = requests.post(
              "https://hub.oxen.ai/api/ai/videos/generate",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>"
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Basic parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/videos/generate \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>",
            "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
          }'
          ```

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

          response = requests.post(
              "https://hub.oxen.ai/api/ai/videos/generate",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>",
                  "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          curl -X POST https://hub.oxen.ai/api/ai/videos/generate \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>",
            "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "aspect_ratio": "16:9",
            "resolution": "1080p",
            "duration": 8
          }'
          ```

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

          response = requests.post(
              "https://hub.oxen.ai/api/ai/videos/generate",
              headers={
                  "Content-Type": "application/json",
                  "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
              },
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>",
                  "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "aspect_ratio": "16:9",
                  "resolution": "1080p",
                  "duration": 8
              },
          )
          response.raise_for_status()
          print(response.json())
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Async">
    See the [async queue reference](/inference-api/reference/async_queue) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>"
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

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

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>"
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Basic parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>",
            "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

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

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>",
                  "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>",
            "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "aspect_ratio": "16:9",
            "resolution": "1080p",
            "duration": 8
          }' | jq -r '.generations[0].generation_id')

          # Poll until the generation reaches a terminal status.
          while true; do
            STATUS=$(curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
              "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq -r '.status')
            echo "Status: $STATUS"
            case $STATUS in succeeded|failed|cancelled) break;; esac
            sleep 5
          done

          # Print the result.
          curl -s -H "Authorization: Bearer $OXEN_API_KEY" \
            "https://hub.oxen.ai/api/ai/queue/$GEN_ID" | jq .
          ```

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

          HEADERS = {
              "Content-Type": "application/json",
              "Authorization": f"Bearer {os.environ['OXEN_API_KEY']}",
          }

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers=HEADERS,
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>",
                  "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "aspect_ratio": "16:9",
                  "resolution": "1080p",
                  "duration": 8
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          while True:
              data = requests.get(
                  f"https://hub.oxen.ai/api/ai/queue/{generation_id}",
                  headers=HEADERS,
              ).json()
              if data["status"] in {"succeeded", "failed", "cancelled"}:
                  break
              time.sleep(5)

          if data["status"] == "succeeded":
              print(f"Result: {data['result_url']}")
          else:
              print(f"Generation {data['status']}: {data.get('error_message')}")
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Async with SSE">
    See the [async queue reference](/inference-api/reference/async_queue) for more details.

    <Tabs>
      <Tab title="Minimal">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>"
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

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

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>"
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>

      <Tab title="Basic parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>",
            "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

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

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>",
                  "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png"
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>

      <Tab title="All parameters">
        <CodeGroup>
          ```bash cURL theme={null}
          # Enqueue, capture the generation id.
          GEN_ID=$(curl -s -X POST https://hub.oxen.ai/api/ai/queue \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OXEN_API_KEY" \
            -d '{
            "model": "google-veo-3-1",
            "prompt": "<prompt>",
            "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
            "aspect_ratio": "16:9",
            "resolution": "1080p",
            "duration": 8
          }' | jq -r '.generations[0].generation_id')

          # Stream the SSE channel, grab the data line that follows a
          # media_generation_completed event for our id, and pretty-print it.
          curl -sN -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/events \
            | awk -v id="$GEN_ID" '
              /^event: media_generation_completed$/ { expect=1; next }
              /^data: / && expect {
                payload = substr($0, 7)
                if (index(payload, "\"generation_id\":\"" id "\"")) { print payload; exit }
                expect = 0
              }
            ' | jq .
          ```

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

          API_KEY = os.environ["OXEN_API_KEY"]
          AUTH = {"Authorization": f"Bearer {API_KEY}"}

          enqueue = requests.post(
              "https://hub.oxen.ai/api/ai/queue",
              headers={**AUTH, "Content-Type": "application/json"},
              json={
                  "model": "google-veo-3-1",
                  "prompt": "<prompt>",
                  "input_image": "https://hub.oxen.ai/api/repos/elau/assets/file/main/bloxy/bloxy_cropped_512x512.png",
                  "aspect_ratio": "16:9",
                  "resolution": "1080p",
                  "duration": 8
              },
          )
          enqueue.raise_for_status()
          generation_id = enqueue.json()["generations"][0]["generation_id"]

          with requests.get(
              "https://hub.oxen.ai/api/events",
              headers=AUTH,
              stream=True,
          ) as stream:
              event_name = None
              for line in stream.iter_lines(decode_unicode=True):
                  if line.startswith("event: "):
                      event_name = line.removeprefix("event: ")
                  elif line.startswith("data: ") and event_name == "media_generation_completed":
                      payload = json.loads(line.removeprefix("data: "))
                      if payload.get("generation_id") == generation_id:
                          print(payload)
                          break
          ```
        </CodeGroup>
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

## Fetch model details

The [models endpoint](/inference-api/reference/models/overview) returns the full model object, including its `json_request_schema`.

```bash theme={null}
curl -H "Authorization: Bearer $OXEN_API_KEY" https://hub.oxen.ai/api/ai/models/google-veo-3-1
```

## Request parameters

### Required parameters

| Field    | Type     | Default | Description                                                                   |
| -------- | -------- | ------- | ----------------------------------------------------------------------------- |
| `prompt` | `string` | —       | Text description of the video to generate, or how to animate the input image. |

### Optional parameters

| Field          | Type      | Default   | Description                                                                                                                                          |
| -------------- | --------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `input_image`  | `string`  | —         | Optional first-frame image to animate (image-to-video). Leave empty to generate from the prompt alone. Must be jpeg, png, gif, or webp. Format: uri. |
| `aspect_ratio` | `string`  | `"16:9"`  | Video aspect ratio One of: 16:9, 9:16.                                                                                                               |
| `resolution`   | `string`  | `"1080p"` | Resolution of the generated video. 1080p and 4k require an 8 second duration. One of: 720p, 1080p, 4k.                                               |
| `duration`     | `integer` | `8`       | Video duration in seconds. 1080p and 4k require 8 seconds. One of: 4, 6, 8.                                                                          |
