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

# Create a video job

> Submit an async video job. Poll GET /videos/{id}, or register a signed webhook (POST /webhooks or https://www.ninjachat.ai/developers/webhooks) for video.completed / video.failed.



## OpenAPI

````yaml /openapi.json post /videos
openapi: 3.1.0
info:
  title: NinjaChat API
  version: 1.0.0
  description: >-
    Clean-break NinjaChat v1. Chat and Responses bill actual token usage; images
    and videos use catalog unit pricing.
servers:
  - url: https://www.ninjachat.ai/api/v1
security: []
paths:
  /videos:
    post:
      summary: Create a video job
      description: >-
        Submit an async video job. Poll GET /videos/{id}, or register a signed
        webhook (POST /webhooks or https://www.ninjachat.ai/developers/webhooks)
        for video.completed / video.failed.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoCreateRequest'
      responses:
        '200':
          description: Queued video job.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VideoCreateResponse'
        '400':
          description: Invalid or unsupported request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '402':
          description: Insufficient balance or project spend limit reached.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Gateway error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - bearerAuth: []
      x-codeSamples:
        - lang: javascript
          label: TypeScript SDK
          source: >-
            import { NinjaChat } from "@ninjachat/sdk";


            const client = new NinjaChat({ apiKey:
            process.env.NINJACHAT_API_KEY! });


            const job = await client.videos.generate({
              model: "veo-3.1-fast",
              prompt: "A slow aerial pass over a neon city in the rain",
            });


            console.log(job.id);
        - lang: python
          label: Python SDK
          source: |-
            import os
            from ninjachat import NinjaChat

            client = NinjaChat(api_key=os.environ["NINJACHAT_API_KEY"])

            job = client.videos.generate(
                model="veo-3.1-fast",
                prompt="A slow aerial pass over a neon city in the rain",
            )

            print(job["id"])
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        minLength: 1
        maxLength: 255
      description: >-
        Safely retry the same logical write without duplicate billing or
        execution.
  schemas:
    VideoCreateRequest:
      type: object
      properties:
        prompt:
          type: string
          minLength: 1
          maxLength: 4000
        model:
          type: string
          enum:
            - nova-reel
            - runway-gen4.5
            - flux-3-video
            - minimax-h3
            - hailuo-2.3
            - hailuo-2.3-fast
            - happyhorse-1.1
            - ray-3.2
            - seedance-2.5
            - seedance-2
            - seedance-2.0-fast
            - seedance-2-mini
            - seedance-2.0
            - seedance-1.5-pro
            - seedance-lite
            - seedance-pro
            - grok-imagine-video
            - grok-imagine-video-1.5
            - kling-2.5-turbo
            - kling-3
            - kling-3-pro
            - kling-3-turbo
            - kling-3-omni
            - wan-2.7
            - wan-2.7-i2v
            - wan-2.7-r2v
            - wan-2.6
            - wan-2.6-i2v
            - wan-2.2-t2v-a14b
            - fast-wan-2.2
            - fast-wan-qad
            - pruna-p-video
            - pixverse-6
            - pixverse-6-i2v
            - cosmos-3-nano
            - cosmos-3-super
            - vidu-q3
            - veo-3.1
            - veo-3.1-fast
            - gemini-omni-flash
            - kling-video
            - google-veo-2
            - google-veo-3-fast
            - google-veo-3.1
            - google-veo-3.1-fast
            - google-veo
            - seedance-2-video
            - seedance-video
          default: veo-3.1-fast
        duration:
          type: integer
          minimum: 3
          maximum: 15
          default: 8
        aspect_ratio:
          type: string
          enum:
            - '16:9'
            - '9:16'
            - '1:1'
          default: '16:9'
        image_url:
          type: string
          format: uri
        end_image_url:
          type: string
          format: uri
        reference_images:
          type: array
          items:
            type: string
            format: uri
          maxItems: 4
        reference_video:
          type: string
          format: uri
        reference_audio:
          type: string
          format: uri
        generate_audio:
          type: boolean
          default: false
        negative_prompt:
          type: string
        watermark:
          type: boolean
          default: false
        video_id:
          type: string
          pattern: ^vid_[A-Za-z0-9-]+$
          description: >-
            Revise a finished clip in place instead of starting from scratch:
            the id returned by POST /videos. The prompt then describes the
            change (task edit, the default) or what happens next (task extend).
            Only gemini-omni-flash clips can be revised, and model must match
            the clip; leave model out to inherit it.
        task:
          type: string
          enum:
            - edit
            - extend
          description: >-
            With video_id: edit keeps the clip's length and changes its content;
            extend appends duration seconds (3–10) of new footage, up to 40
            seconds total. Defaults to edit.
      required:
        - prompt
      additionalProperties: false
    VideoCreateResponse:
      type: object
      properties:
        cost:
          type: object
          properties:
            this_request:
              type: string
            per_image:
              type: string
            per_video:
              type: string
            images:
              type: integer
              minimum: 0
          required:
            - this_request
          additionalProperties: false
        balance:
          type: string
        metadata:
          type: object
          properties:
            latency_ms:
              type: number
              minimum: 0
            group:
              type: string
            search_depth:
              type: string
            results_count:
              type: integer
              minimum: 0
          required:
            - latency_ms
          additionalProperties: false
        message:
          type: string
        id:
          type: string
        object:
          type: string
          enum:
            - video
        status:
          type: string
          enum:
            - queued
        model:
          type: string
          minLength: 1
          maxLength: 160
        cost_usd:
          type: number
          minimum: 0
        request_id:
          type: string
        trace_request_id:
          type: string
          description: >-
            Original request receipt ID, also returned in X-Request-ID. Use id
            or request_id to poll the video job.
      required:
        - id
        - object
        - status
        - model
        - cost_usd
        - request_id
      additionalProperties: false
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
            type:
              type: string
            code:
              type: string
            param:
              type:
                - string
                - 'null'
          required:
            - message
            - type
            - code
          additionalProperties: false
      required:
        - error
      additionalProperties: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: NinjaChat API key
      description: Use an API key created in the NinjaChat developer console.

````