The media library is the store's catalog of uploaded images, video, and documents. Add files by uploading them directly or by pointing at remote URLs (re-hosted on the store CDN), then attach them to products, variants, or collections.

## List Media

```
GET /api/v1/media
```

Returns a paginated list of the store's media, newest first. Filter by `kind` and search filename or alt text with `query`.

### Query Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | `number` | 24 | Items per page (1-100) |
| `offset` | `number` | 0 | Items to skip |
| `kind` | `"image" \| "video" \| "document"` | – | Filter by media kind |
| `query` | `string` | – | Search by filename or alt text |

```bash
curl -H "Authorization: Bearer your_api_key" \
  "https://your-store.yns.store/api/v1/media?kind=image&limit=24"
```

### Response

```json
{
  "data": [
    {
      "id": "0191abc0-1234-7def-8000-000000000001",
      "url": "https://cdn.example.com/images/store/live/hero-a1b2.jpg",
      "pathname": "images/store/live/hero-a1b2.jpg",
      "filename": "hero.jpg",
      "kind": "image",
      "mimeType": "image/jpeg",
      "width": 1600,
      "height": 900,
      "sizeBytes": 248213,
      "source": "upload",
      "alt": "Storefront hero banner",
      "createdAt": "2024-06-15T10:30:00.000Z",
      "updatedAt": "2024-06-15T10:30:00.000Z"
    }
  ],
  "meta": {
    "count": 1,
    "limit": 24,
    "offset": 0
  }
}
```

---

## Create Media

```
POST /api/v1/media
```

Adds media to the library in one of two modes, chosen by the request `Content-Type`.

**File upload** (`multipart/form-data`) – upload file(s) under the `file` field; repeat the field for multiple files. Maximum 10 files, 25 MB each.

**Remote URLs** (`application/json`) – pass `{ "urls": [...] }` to fetch remote images and re-host them on the store CDN (images only).

Both modes catalog the result and return the created rows under `media`.

### Request Body (JSON mode)

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `urls` | `string[]` | Yes | Remote image URLs to fetch and add (min 1) |

```bash
# File upload
curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -F "file=@hero.jpg" \
  -F "file=@thumbnail.png" \
  https://your-store.yns.store/api/v1/media

# Remote URLs
curl -X POST \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com/photo.jpg"]}' \
  https://your-store.yns.store/api/v1/media
```

### Response (201)

```json
{
  "media": [
    {
      "id": "0191abc0-1234-7def-8000-000000000002",
      "url": "https://cdn.example.com/images/store/live/photo-c3d4.jpg",
      "pathname": "images/store/live/photo-c3d4.jpg",
      "filename": "photo.jpg",
      "kind": "image",
      "mimeType": "image/jpeg",
      "width": 1200,
      "height": 800,
      "sizeBytes": 184022,
      "source": "external",
      "alt": null,
      "createdAt": "2024-06-15T10:31:00.000Z",
      "updatedAt": "2024-06-15T10:31:00.000Z"
    }
  ]
}
```

---

## Get Media

```
GET /api/v1/media/:id
```

Returns a single media item by ID. Returns `404` if it does not exist in this store.

```bash
curl -H "Authorization: Bearer your_api_key" \
  https://your-store.yns.store/api/v1/media/0191abc0-1234-7def-8000-000000000001
```

---

## Update Media

```
PATCH /api/v1/media/:id
```

Updates editable metadata. Send at least one field – an empty body returns `400`.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `filename` | `string` | No | Display filename (min 1 char) |
| `alt` | `string \| null` | No | Alt text for accessibility (`null` to clear) |

```bash
curl -X PATCH \
  -H "Authorization: Bearer your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"alt": "Storefront hero banner"}' \
  https://your-store.yns.store/api/v1/media/0191abc0-1234-7def-8000-000000000001
```

### Response (200)

Returns the updated media item.

---

## Delete Media

```
DELETE /api/v1/media/:id
```

Removes the media row and best-effort deletes the underlying blob. If the asset is still attached to one or more products, variants, or collections, the request returns `409` with the list of `usedBy` entities. Pass `?force=true` to delete anyway – the URL is stripped from every entity that references it.

### Query Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `force` | `boolean` | `false` | Delete even if the asset is still attached |

```bash
curl -X DELETE \
  -H "Authorization: Bearer your_api_key" \
  "https://your-store.yns.store/api/v1/media/0191abc0-1234-7def-8000-000000000001?force=true"
```

### Response (204)

Empty body on success.

### In Use (409)

```json
{
  "error": "Media is attached to one or more items. Detach it first or pass ?force=true.",
  "usedBy": [
    {
      "entityType": "product",
      "entityId": "0191abc0-0000-7000-8000-000000000100",
      "role": "gallery"
    }
  ]
}
```