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

# Create Scene

> Upload a driving video to create a reusable scene

Upload a driving video and we'll turn it into a reusable scene — it captures the motion you can then apply to any character. **Creating a scene is free; you only spend credits when you render.**

<Warning>
  **Video limits:** Maximum **10 minutes** duration and **100 MB** file size.
</Warning>

### Parameters

| Parameter | Type   | Required | Description                                               |
| --------- | ------ | :------: | --------------------------------------------------------- |
| `video`   | file   |     ✅    | Driving video (MP4, MOV, AVI, WebM). Max 10 min / 100 MB. |
| `name`    | string |     ✅    | Display name for the scene.                               |

## Response

```json theme={null}
{
  "id": "660e8400-e29b-41d4-a716-446655440000",
  "job_id": "scene_660e8400e29b",
  "status": "pending",
  "credits_reserved": 0,
  "message": "Scene preprocessing initiated (6.7s video, 7 chunks). Check status for updates."
}
```

| Field              | Description                                                                                                |
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
| `id`               | Scene UUID. Poll [Get Scene](/api-reference/scenes/get) with it, then use it as `scene_id` when rendering. |
| `status`           | Starts at `pending`; preprocessing runs in the background.                                                 |
| `credits_reserved` | Always `0` — scene creation is free. Credits are charged at render time.                                   |

## Example

<CodeGroup>
  ```python Python theme={null}
  import requests

  url = "https://apis.viggle.ai/api/scenes/preprocess"
  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
  }
  files = {
      "video": ("driving_video.mp4", open("driving_video.mp4", "rb"), "video/mp4"),
  }
  data = {
      "name": "My Scene",
  }

  response = requests.post(url, headers=headers, files=files, data=data)
  response.raise_for_status()
  result = response.json()

  print(f"Scene ID: {result['id']}")
  print(f"Status: {result['status']}")
  ```

  ```javascript JavaScript theme={null}
  const form = new FormData();
  form.append("video", new Blob([await fetch("driving_video.mp4").then(r => r.blob())]), "driving_video.mp4");
  form.append("name", "My Scene");

  const response = await fetch("https://apis.viggle.ai/api/scenes/preprocess", {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_API_KEY",
    },
    body: form,
  });

  const result = await response.json();

  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  console.log(`Scene ID: ${result.id}`);
  console.log(`Status: ${result.status}`);
  ```

  ```bash cURL theme={null}
  curl -X POST https://apis.viggle.ai/api/scenes/preprocess \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -F "video=@driving_video.mp4" \
    -F "name=My Scene"
  ```
</CodeGroup>

## Next Steps

After creating a scene, poll [Get Scene](/api-reference/scenes/get) every 5 seconds until the status becomes `ready`. Then you can use it in [render jobs](/api-reference/render/create).

<Tip>
  **Don't have a driving video?** You can [import a template from viggle.ai](/guides/import-templates) instead of uploading your own video. Templates include pre-made scenes ready for rendering.
</Tip>


## OpenAPI

````yaml POST /api/scenes/preprocess
openapi: 3.0.3
info:
  title: Viggle API
  description: Generate AI-powered character animation videos
  version: 2.0.0
  contact:
    name: Viggle Support
    url: https://viggle.ai
servers:
  - url: https://apis.viggle.ai
    description: Production server
security: []
paths:
  /api/scenes/preprocess:
    post:
      tags:
        - Scenes
      summary: Create Scene
      description: >-
        Upload a driving video to create a reusable scene. Extracts motion data
        for character animation. Scene creation is free — credits are consumed
        at render time. Poll GET /api/scenes/{id} until status is ready.
      operationId: createScene
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - name
                - video
              properties:
                name:
                  type: string
                  description: Display name for the scene
                  example: Dance Sequence
                video:
                  type: string
                  format: binary
                  description: >-
                    Driving video file (MP4, MOV, AVI, WebM). Maximum 10 minutes
                    duration and 100 MB file size.
      responses:
        '200':
          description: Scene creation started
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SceneCreated'
        '400':
          description: Invalid video type
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorStructured'
              example:
                detail:
                  error_code: CS-UORC01-002
                  message: >-
                    Invalid video. Upload an MP4, MOV, AVI, or WebM file within
                    the size and duration limits.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
      security:
        - bearerAuth: []
components:
  schemas:
    SceneCreated:
      type: object
      properties:
        id:
          type: string
          example: 660e8400-e29b-41d4-a716-446655440000
          description: Scene UUID
        job_id:
          type: string
          example: scene_660e8400e29b
        status:
          type: string
          example: pending
        credits_reserved:
          type: number
          example: 0
          description: >-
            Credits reserved for scene preprocessing (always 0 — scene creation
            is free)
        message:
          type: string
          example: >-
            Scene preprocessing initiated (6.7s video, 7 chunks). Check status
            for updates.
    ErrorStructured:
      type: object
      description: >-
        Structured error. `detail` carries a machine-readable `error_code` plus
        a human-readable `message`.
      properties:
        detail:
          type: object
          properties:
            error_code:
              type: string
              example: CS-UORC01-008
            message:
              type: string
              example: Insufficient credits. Top up your balance to continue.
    Error:
      type: object
      description: >-
        Simple error. `detail` is a human-readable message (used for auth
        errors).
      properties:
        detail:
          type: string
          example: 'API key required. Use Authorization: Bearer sk-xxx'
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            detail: >-
              Invalid or missing API key. Pass it as Authorization: Bearer
              sk-...
    InsufficientCredits:
      description: Insufficient credits
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorStructured'
          example:
            detail:
              error_code: CS-UORC01-008
              message: Insufficient credits. Top up your balance to continue.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key passed as Bearer token

````