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

# Duplicate Video

> Duplicate an existing completed video, optionally with a new voice and/or avatar look

## Overview

This endpoint duplicates an existing completed video inside the same space.

* If **no optional parameters** are provided, it creates an exact copy of the video.
* You can **optionally apply** a new voice and/or a new avatar look to the duplicated video while keeping the original script, structure, and media.

The original video must belong to your space and be in `done` status.

## Authentication

<Info>
  This endpoint requires API key authentication. Include your API key in the `Authorization` header.
</Info>

## Request Body

<ParamField body="video_id" type="string" required>
  Unique identifier of the original video to duplicate.\
  The video must belong to your space and be in `done` status (completed generation).
</ParamField>

<ParamField body="avatar_look_id" type="string">
  Optional ID of the avatar look to apply on the duplicated video.\
  Use an ID returned by the [avatar resources endpoint](/api-reference/resources/avatars) or from your custom avatars.\
  When provided, the duplicated video will reference this new look, and avatar renders will be regenerated as needed.
</ParamField>

<ParamField body="voice_id" type="string">
  Optional ID of the voice to use for the duplicated video.\
  Use an ID returned by the [voice resources endpoint](/api-reference/resources/voices) or from your custom voices.\
  For standard videos, the endpoint regenerates the audio and subtitles with the new voice.\
  For native avatar videos (generated with `use_native_avatar`), audio is generated later during export.
</ParamField>

## Response

<ResponseField name="video_id" type="string">
  Unique identifier of the newly duplicated video.
</ResponseField>

<ResponseField name="status" type="string">
  Current status of the duplicated video.\
  Typically `done`, meaning the video is ready to be exported.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable message describing the result of the duplication.
</ResponseField>

<ResponseField name="changes_applied" type="object">
  Details of which changes were applied to the duplicated video.

  <Expandable title="properties">
    <ResponseField name="voice_changed" type="boolean">
      `true` if a new voice was applied using `voice_id`.
    </ResponseField>

    <ResponseField name="avatar_changed" type="boolean">
      `true` if a new avatar look was applied using `avatar_look_id`.
    </ResponseField>
  </Expandable>
</ResponseField>

## Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://app.hoox.video/api/public/v1/video/duplicate" \
    -H "Authorization: Bearer your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
      "video_id": "vid_abc123",
      "voice_id": "voice_en_us_female_1",
      "avatar_look_id": "avatar_business_woman_office_1"
    }'
  ```

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

  url = "https://app.hoox.video/api/public/v1/video/duplicate"
  headers = {
      "Authorization": "Bearer your_api_key",
      "Content-Type": "application/json"
  }

  data = {
      "video_id": "vid_abc123",
      "voice_id": "voice_en_us_female_1",
      "avatar_look_id": "avatar_business_woman_office_1"
  }

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

  ```javascript JavaScript theme={null}
  const response = await fetch('https://app.hoox.video/api/public/v1/video/duplicate', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer your_api_key',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      video_id: "vid_abc123",
      voice_id: "voice_en_us_female_1",
      avatar_look_id: "avatar_business_woman_office_1"
    })
  });

  const data = await response.json();
  console.log(data);
  ```
</RequestExample>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "video_id": "vid_dup_456",
    "status": "done",
    "message": "Video duplicated successfully. The video will need to be exported to generate the final output.",
    "changes_applied": {
      "voice_changed": true,
      "avatar_changed": true
    }
  }
  ```

  ```json Error 400 - Missing Video ID theme={null}
  {
    "error": "Validation failed",
    "details": [
      {
        "code": "MISSING_VIDEO_ID",
        "message": "video_id is required",
        "field": "video_id"
      }
    ]
  }
  ```

  ```json Error 404 - Video Not Found theme={null}
  {
    "error": "Video not found",
    "details": [
      {
        "code": "VIDEO_NOT_FOUND",
        "message": "Video with ID \"vid_abc123\" not found"
      }
    ]
  }
  ```

  ```json Error 403 - Unauthorized Video theme={null}
  {
    "error": "Unauthorized",
    "details": [
      {
        "code": "UNAUTHORIZED_VIDEO",
        "message": "This video does not belong to your space"
      }
    ]
  }
  ```

  ```json Error 400 - Video Not Ready theme={null}
  {
    "error": "Video not ready",
    "details": [
      {
        "code": "VIDEO_NOT_READY",
        "message": "Only completed videos can be duplicated"
      }
    ]
  }
  ```
</ResponseExample>

## Prerequisites

Before duplicating a video:

1. **Completed video**: The original video must be in `done` status.
2. **Video ownership**: The video must belong to your space.
3. **Valid video\_id**: Provide the ID of an existing video in your space.

## Error Codes

* `MISSING_VIDEO_ID`: `video_id` parameter is required.
* `INVALID_TYPE`: One of the parameters has an invalid type (must be strings).
* `INVALID_VOICE_ID`: Provided `voice_id` does not match any available voice.
* `INVALID_AVATAR_ID`: Provided `avatar_look_id` does not match any available avatar look.
* `VIDEO_NOT_FOUND`: Video with specified ID does not exist.
* `UNAUTHORIZED_VIDEO`: Video does not belong to your space.
* `VIDEO_NOT_READY`: Video must be completed before duplication.
* `INTERNAL_ERROR`: Unexpected internal server error.
