# Media

> 5 endpoints: list media, retrieve media, start a media upload, sign video upload parts, complete a media upload.

- [List media](#list-media): `GET /v1/media`
- [Retrieve media](#retrieve-media): `GET /v1/media/{media_id}`
- [Start a media upload](#start-a-media-upload): `POST /v1/media`
- [Sign video upload parts](#sign-video-upload-parts): `POST /v1/media/{media_id}/parts`
- [Complete a media upload](#complete-a-media-upload): `POST /v1/media/{media_id}/complete`

### List media

`GET /v1/media`

Lists uploaded videos, images and thumbnails, newest first.

Permission: `media:read`

#### Query parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | integer | No | Items per page, 1 to 100. (1 to 100, default 25) |
| `cursor` | string | No | The next_cursor of the previous page. (up to 512 characters) |
| `project_id` | string | No |  (up to 128 characters) |

#### Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"list"` | Yes |  |
| `data` | array of object | Yes |  |
| `data[].object` | `"media"` | Yes |  |
| `data[].id` | string | Yes |  (up to 128 characters) |
| `data[].project_id` | string or null | Yes |  |
| `data[].kind` | `video`, `image`, `thumbnail` | Yes |  |
| `data[].status` | string | Yes |  |
| `data[].content_type` | string | Yes |  |
| `data[].size_bytes` | integer or null | Yes |  |
| `data[].created_at` | string | Yes | ISO 8601 date and time, UTC. |
| `has_more` | boolean | Yes |  |
| `next_cursor` | string or null | Yes |  |

```bash
curl https://api.nowscale.com/v1/media \
  -H "Authorization: Bearer $NOWSCALE_API_KEY"
```

### Retrieve media

`GET /v1/media/{media_id}`

Returns one uploaded file.

Permission: `media:read`

#### Path parameters

| Name | Description |
| --- | --- |
| `media_id` | The media's id. |

#### Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"media"` | Yes |  |
| `id` | string | Yes |  (up to 128 characters) |
| `project_id` | string or null | Yes |  |
| `kind` | `video`, `image`, `thumbnail` | Yes |  |
| `status` | string | Yes |  |
| `content_type` | string | Yes |  |
| `size_bytes` | integer or null | Yes |  |
| `created_at` | string | Yes | ISO 8601 date and time, UTC. |

```bash
curl https://api.nowscale.com/v1/media/MEDIA_ID \
  -H "Authorization: Bearer $NOWSCALE_API_KEY"
```

### Start a media upload

`POST /v1/media`

Reserves a media item in a Project and returns where to send the file. Images and thumbnails take one PUT to upload_url; videos upload in parts (sign them with the parts endpoint). Finish with the complete endpoint.

Permission: `media:write` · Accepts `Idempotency-Key` · Answers `201`

#### Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | string | Yes |  (up to 128 characters) |
| `kind` | `video`, `image`, `thumbnail` | Yes |  |
| `content_type` | string | Yes |  (up to 127 characters) |
| `size_bytes` | integer | Yes |  (at most 9007199254740991) |

#### Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"media_upload"` | Yes |  |
| `media_id` | string | Yes |  (up to 128 characters) |
| `method` | `single`, `multipart` | Yes |  |
| `upload_url` | string or null | Yes | single: PUT the file here with its Content-Type. |
| `part_size` | integer or null | Yes | multipart: bytes per part (the last part may be smaller). |
| `part_count` | integer or null | Yes |  |
| `content_type` | string | Yes |  |

```bash
curl -X POST https://api.nowscale.com/v1/media \
  -H "Authorization: Bearer $NOWSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ ... }'
```

### Sign video upload parts

`POST /v1/media/{media_id}/parts`

Returns a short-lived PUT URL for each part number of a video upload. Keep the ETag header of each part's response for the complete endpoint.

Permission: `media:write`

#### Path parameters

| Name | Description |
| --- | --- |
| `media_id` | The media's id. |

#### Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `part_numbers` | array of integer | Yes |  |

#### Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"media_part_urls"` | Yes |  |
| `media_id` | string | Yes |  (up to 128 characters) |
| `urls` | object | Yes |  |

```bash
curl -X POST https://api.nowscale.com/v1/media/MEDIA_ID/parts \
  -H "Authorization: Bearer $NOWSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
```

### Complete a media upload

`POST /v1/media/{media_id}/complete`

Checks the uploaded file and makes it ready to attach to posts. Videos list every part with its ETag. Duration and size you report are checked again by each network at publish time.

Permission: `media:write` · Accepts `Idempotency-Key`

#### Path parameters

| Name | Description |
| --- | --- |
| `media_id` | The media's id. |

#### Body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `parts` | array of object | No |  |
| `parts[].part_number` | integer | Yes |  (1 to 10000) |
| `parts[].etag` | string | Yes |  (up to 256 characters) |
| `duration_seconds` | number | No |  (at most 172800) |
| `width` | integer | No |  (at most 16384) |
| `height` | integer | No |  (at most 16384) |

#### Response

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | `"media"` | Yes |  |
| `id` | string | Yes |  (up to 128 characters) |
| `project_id` | string or null | Yes |  |
| `kind` | `video`, `image`, `thumbnail` | Yes |  |
| `status` | string | Yes |  |
| `content_type` | string | Yes |  |
| `size_bytes` | integer or null | Yes |  |
| `created_at` | string | Yes | ISO 8601 date and time, UTC. |

```bash
curl -X POST https://api.nowscale.com/v1/media/MEDIA_ID/complete \
  -H "Authorization: Bearer $NOWSCALE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ ... }'
```
