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

# Create Artifact

> Create a new artifact from an uploaded file or external source

This endpoint creates an artifact record and initiates file processing. Use this endpoint after uploading a file via presigned URL, or directly with external URLs/S3 paths.

<Note>
  **Uploading a local file?** First get a presigned URL using [Get Presigned Upload URL](/studio/endpoints/artifacts/get-presigned-upload-url), upload your file, then use this endpoint with the S3 path.
</Note>

<Note>
  Can handle files up to 5GB.
</Note>

<Card title="Observe your artifacts" icon="table-list" href="https://studio.dubformer.ai/artifacts">
  View and track all your artifacts and their processing status in real-time via the [Artifacts Dashboard](https://studio.dubformer.ai/artifacts).
</Card>

## Request Body

<ParamField body="name" type="string" required>
  Display name of the artifact. E.g., `My Project Video`.
</ParamField>

<ParamField body="type" type="string" required>
  Type of artifact. Must be one of:

  * `video` - Video files
  * `audio` - Audio files
  * `script` - Text/script files
</ParamField>

### Source Parameters

Choose **exactly one** of the following parameters to specify your file source:

<ParamField body="s3Path" type="string">
  S3 path to the file. Can be:

  * Path from [Get Presigned Upload URL](/studio/endpoints/artifacts/get-presigned-upload-url) (e.g., `s3://dubformer-temp/uploads/aafa1753/file.mp4`)
  * External S3 bucket path (e.g., `s3://my-bucket/path/to/file.mp4`) - requires S3 credentials configured

  **Use when:** File is already in S3 or uploaded via presigned URL
</ParamField>

<ParamField body="url" type="string">
  Direct URL to download the artifact from an external source.

  Must be a publicly accessible URL. The file will be downloaded asynchronously.

  **Use when:** File is hosted on a CDN, public storage, or web server
</ParamField>

<ParamField body="fragments" type="array">
  Array of media fragments to concatenate into a single artifact.

  Not supported for `script` type. Each fragment object must contain:

  * `url` or `s3Path` - source location
  * `startTime` - start time in seconds (must be >= 0)

  All fragments must have the same format (codec, resolution, frame rate).

  **Use when:** Combining multiple clips into one file
</ParamField>

<Tip>
  **Using external AWS S3?** To enable external S3 paths or S3 fragments, configure AWS credentials for your API key in Dashboard Settings → API Keys → Select your key → S3 Credentials.
</Tip>

## Response

Returns a complete artifact object:

<ResponseField name="id" type="string">
  Unique identifier for the artifact. Use this to retrieve artifact status or use in other endpoints.
</ResponseField>

<ResponseField name="name" type="string">
  Display name of the artifact.
</ResponseField>

<ResponseField name="type" type="string">
  Type of artifact: `video`, `audio`, or `script`.
</ResponseField>

<ResponseField name="status" type="string">
  Current processing status. Possible values:

  * `created` - Artifact created, processing pending
  * `upload_started` - File is being downloaded/copied/processed
  * `upload_completed` - File is ready for use
  * `upload_failed` - Processing failed (check `errorMessage`)
</ResponseField>

<ResponseField name="uploadMethod" type="string">
  Upload method used:

  * `direct_url` - Presigned upload, direct URL, or S3 path
  * `fragments` - Fragment concatenation
</ResponseField>

<ResponseField name="size" type="number | null">
  File size in bytes. Will be `null` until processing completes.
</ResponseField>

<ResponseField name="duration" type="number | null">
  Duration in seconds (for video/audio). Will be `null` until processing completes or for script type.
</ResponseField>

<ResponseField name="errorMessage" type="string | null">
  Error message if processing failed. Will be `null` unless status is `upload_failed`.
</ResponseField>

<ResponseField name="s3Path" type="string">
  Internal S3 path where the artifact file is stored (without bucket prefix).
</ResponseField>

<ResponseField name="s3Bucket" type="string">
  S3 bucket name where the artifact is stored.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 timestamp when the artifact was created.
</ResponseField>

<ResponseField name="updatedAt" type="string">
  ISO 8601 timestamp when the artifact was last updated.
</ResponseField>

<ResponseField name="company" type="object | undefined">
  Company information object containing `id` and `name` fields.
</ResponseField>

<ResponseField name="createdBy" type="object | undefined">
  User information object containing `id` and `name` fields for the user who created the artifact.
</ResponseField>

## Request Examples

<RequestExample>
  ```bash Presigned Upload theme={null}
  # After uploading file via presigned URL
  curl -X POST \
    https://studio.dubformer.ai/api/v1/artifacts/create \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "name": "My Source Video",
      "type": "video",
      "s3Path": "s3://dubformer-artifacts/temp/550e8400-e29b-41d4-a716-446655440000/video.mp4"
    }'
  ```

  ```bash Direct URL theme={null}
  curl -X POST \
    https://studio.dubformer.ai/api/v1/artifacts/create \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "name": "Marketing Video",
      "type": "video",
      "url": "https://cdn.example.com/videos/promo.mp4"
    }'
  ```

  ```bash External S3 Path theme={null}
  curl -X POST \
    https://studio.dubformer.ai/api/v1/artifacts/create \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "name": "Archive Video",
      "type": "video",
      "s3Path": "s3://my-company-bucket/recordings/meeting-2024.mp4"
    }'
  ```

  ```bash Fragments theme={null}
  curl -X POST \
    https://studio.dubformer.ai/api/v1/artifacts/create \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "name": "Concatenated Video",
      "type": "video",
      "fragments": [
        {
          "url": "https://example.com/intro.mp4",
          "startTime": 0
        },
        {
          "url": "https://example.com/main.mp4",
          "startTime": 10
        },
        {
          "url": "https://example.com/outro.mp4",
          "startTime": 300
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://studio.dubformer.ai/api/v1/artifacts/create',
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: 'My Source Video',
        type: 'video',
        s3Path: 's3://dubformer-artifacts/temp/550e8400-e29b-41d4-a716-446655440000/video.mp4'
      })
    }
  );

  const artifact = await response.json();
  console.log(artifact);
  ```

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

  response = requests.post(
      'https://studio.dubformer.ai/api/v1/artifacts/create',
      headers={
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'name': 'My Source Video',
          'type': 'video',
          's3Path': 's3://dubformer-artifacts/temp/550e8400-e29b-41d4-a716-446655440000/video.mp4'
      }
  )

  artifact = response.json()
  print(artifact)
  ```
</RequestExample>

<ResponseExample>
  ```json Response theme={null}
  {
    "id": "67a8f9b0c1d2e3f4g5h6i7j8",
    "name": "My Source Video",
    "type": "video",
    "status": "created",
    "uploadMethod": "direct_url",
    "size": null,
    "duration": null,
    "errorMessage": null,
    "s3Path": "uploads/67a8f9b0c1d2e3f4g5h6i7j8/video.mp4",
    "s3Bucket": "dubformer-artifacts",
    "createdAt": "2026-02-04T12:00:00.000Z",
    "updatedAt": "2026-02-04T12:00:00.000Z",
    "company": {
      "id": "507f1f77bcf86cd799439011",
      "name": "Acme Inc"
    },
    "createdBy": {
      "id": "507f191e810c19729de860ea",
      "name": "John Doe"
    }
  }
  ```
</ResponseExample>

## Processing Workflow

<Steps>
  <Step title="Create Artifact">
    Send a POST request with one of the source parameters (`s3Path`, `url`, or `fragments`).

    The artifact is created with `created` status.
  </Step>

  <Step title="Background Processing">
    The file is downloaded/copied/processed asynchronously.

    Status transitions to `upload_started` during processing.
  </Step>

  <Step title="Completion">
    When processing completes:

    * Status becomes `upload_completed` (success) or `upload_failed` (error)
    * `size` and `duration` fields are populated
    * If failed, check `errorMessage` for details
  </Step>

  <Step title="Monitor Status">
    Use [Get Artifact](/studio/endpoints/artifacts/get-artifact) to check processing status:

    ```bash theme={null}
    GET /api/v1/artifacts/{artifactId}
    ```
  </Step>
</Steps>

<Warning>
  Artifact processing happens asynchronously. The artifact is created immediately, but the file may not be ready for use until status is `upload_completed`. Always check the status before using the artifact.
</Warning>

## See Also

* [Artifacts Overview](/studio/endpoints/artifacts/overview) - Choose the right upload method
* [Get Presigned Upload URL](/studio/endpoints/artifacts/get-presigned-upload-url) - Upload local files
* [Get Artifact](/studio/endpoints/artifacts/get-artifact) - Check processing status
