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

# Create Product Media

> Attach a media asset to a product via direct URL or Gallery asset.

## Method

`POST` `/v1/products/:id/media`

## Path Parameters

<ParamField path="id" type="uuid" required>Product ID.</ParamField>

## Body Parameters

<ParamField name="url" type="string">Public URL for the media item. Optional if `assetId` is provided.</ParamField>
<ParamField name="assetId" type="string">Gallery asset ID; resolves to a public URL if available.</ParamField>
<ParamField name="kind" type="string">Optional media type (`hero`, `gallery`, etc.).</ParamField>
<ParamField name="alt" type="string">Optional alt text.</ParamField>
<ParamField name="sort" type="integer">Optional sort order (defaults to 0).</ParamField>

At least one of `url` or `assetId` must be supplied (`mediaCreateSchema`).

## Headers

<ParamField header="Authorization" type="string">Bearer token (requires `products:write`).</ParamField>
<ParamField header="content-type" type="string">`application/json`</ParamField>

## Request Example

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.voyantcloud.com/v1/products/prod_123/media" \
    -H "Authorization: Bearer $VOYANT_API_KEY" \
    -H "content-type: application/json" \
    -d '{
      "assetId": "asset_01HZY8SM9P8K4B8N7Q",
      "kind": "hero",
      "alt": "Resort exterior",
      "sort": 0
    }'
  ```

  ```javascript Node.js theme={null}
  await fetch("https://api.voyantcloud.com/v1/products/prod_123/media", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.VOYANT_API_KEY}`,
      "content-type": "application/json",
    },
    body: JSON.stringify({
      url: "https://cdn.example.com/prod_123/gallery-1.jpg",
      kind: "gallery",
      sort: 1,
    }),
  })
  ```

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

  payload = {
    "assetId": "asset_01HZY8SM9P8K4B8N7Q",
    "alt": "Lobby area",
    "kind": "gallery"
  }

  resp = requests.post(
    "https://api.voyantcloud.com/v1/products/prod_123/media",
    headers={
      "Authorization": f"Bearer {os.environ['VOYANT_API_KEY']}",
      "content-type": "application/json",
    },
    json=payload,
  )
  created = resp.json()
  ```
</RequestExample>

## Response Example

<ResponseExample>
  ```json 201 Created theme={null}
  {
    "data": {
      "id": "media_01J0E6V4ZBAVQ9PQJRT2P27QX0",
      "url": "https://cdn.voyantcloud.com/media/prod_123/hero.jpg",
      "kind": "hero",
      "alt": "Resort exterior",
      "sort": 0,
      "assetId": "asset_01HZY8SM9P8K4B8N7Q"
    }
  }
  ```

  ```json 400 Bad Request theme={null}
  {
    "error": "Validation failed",
    "details": [
      { "message": "Either url or assetId must be provided", "path": [] }
    ]
  }
  ```

  ```json 404 Not Found theme={null}
  { "error": "Product not found" }
  ```
</ResponseExample>
