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

# Create User Media

> Upload media to your library from a URL for use in video projects as B-roll

# Create User Media

Upload video or image files to your user media library by providing a URL. This media can then be referenced in your video projects using the returned `userMediaId`.

<Note>
  This endpoint requires authentication and has a rate limit of 500 requests per
  hour.
</Note>

## Authentication

<ParamField header="x-api-key" type="string" required>
  Your Submagic API key starting with `sk-`
</ParamField>

## Request Body

<ParamField body="url" type="string" required>
  Public URL to your video or image file. Must be a valid URL and accessible
  without authentication.
</ParamField>

## Response

<ResponseField name="userMediaId" type="string">
  Unique identifier for the uploaded media (UUID format). Use this ID to
  reference the media in your video projects.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.submagic.co/v1/user-media" \
    -H "x-api-key: sk-your-api-key-here" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com/media/sample-video.mp4"
    }'
  ```

  ```javascript JavaScript theme={null}
  const createUserMedia = async (mediaUrl) => {
    const response = await fetch("https://api.submagic.co/v1/user-media", {
      method: "POST",
      headers: {
        "x-api-key": "sk-your-api-key-here",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        url: mediaUrl,
      }),
    });

    const data = await response.json();
    console.log("User media created:", data.userMediaId);
    return data;
  };

  // Usage
  const media = await createUserMedia(
    "https://example.com/media/sample-video.mp4"
  );
  ```

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

  def create_user_media(media_url):
      url = 'https://api.submagic.co/v1/user-media'
      headers = {
          'x-api-key': 'sk-your-api-key-here',
          'Content-Type': 'application/json'
      }
      data = {
          'url': media_url
      }

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

      print(f"User media created: {result['userMediaId']}")
      return result

  # Usage
  media = create_user_media('https://example.com/media/sample-video.mp4')
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "userMediaId": "88a08eec-712a-45d0-8d0b-3b631700cb3a"
  }
  ```
</ResponseExample>

## Using User Media in Projects

Once you have a `userMediaId`, you can reference it in the `items` array when creating or uploading projects:

```json theme={null}
{
  "items": [
    {
      "type": "user-media",
      "startTime": 5,
      "endTime": 10,
      "userMediaId": "88a08eec-712a-45d0-8d0b-3b631700cb3a",
      "layout": "pip-top-right"
    }
  ]
}
```

See the [Create Project](/api-reference/create-project) or [Upload Project](/api-reference/upload-project) documentation for more details on using user media in your videos.

## Error Responses

<ResponseField name="400 Validation Error" type="object">
  ```json theme={null}
  {
    "error": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "field": "url",
        "message": "Must be a valid URL",
        "value": "invalid-url"
      }
    ]
  }
  ```
</ResponseField>

<ResponseField name="400 Media Not Ready" type="object">
  ```json theme={null}
  {
    "error": "VALIDATION_ERROR",
    "message": "The following media is not ready yet: df7d8cfd-eb82-4865-8b32-df3396b972b1. Please wait for the upload to complete."
  }
  ```
</ResponseField>

<ResponseField name="400 Unsupported Social Media URL" type="object">
  ```json theme={null}
  {
    "error": "VALIDATION_ERROR",
    "message": "URLs from social media platforms are not supported. Please use a direct download link."
  }
  ```
</ResponseField>

<ResponseField name="401 Unauthorized" type="object">
  ```json theme={null}
  {
    "error": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
  ```
</ResponseField>

<ResponseField name="429 Rate Limited" type="object">
  ```json theme={null}
  {
    "error": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "retryAfter": 30
  }
  ```
</ResponseField>

<ResponseField name="500 Server Error" type="object">
  ```json theme={null}
  {
    "error": "INTERNAL_SERVER_ERROR",
    "message": "An unexpected error occurred"
  }
  ```
</ResponseField>
