# Uploads API

Your media library: upload and list images, videos, audio and fonts.

Authenticate with a [personal token](/docs/api#personal-tokens) as `Authorization: Bearer pxp_...`; the operations are also [MCP tools](/docs/connect-ai) unless noted. The full machine-readable definition is in the [OpenAPI specification](https://pxstudio.cloud/api/v1/openapi.json).

| Operation | Method and path | Scope |
| --- | --- | --- |
| [List uploads](#list-uploads) | `GET /uploads` | `overlays:read` |
| [Upload media file](#upload-media-file) | `POST /uploads` | `uploads:write` |
| [Delete upload](#delete-upload) | `DELETE /uploads/{uploadId}` | `uploads:write` |
| [Rename upload](#rename-upload) | `PATCH /uploads/{uploadId}` | `uploads:write` |

## Operations

### List uploads

```http Endpoint
GET /api/v1/uploads
```

Lists your media library (images, video, audio, fonts) with urls usable as image/media sources in layer settings.

**Scope:** `overlays:read` (Read overlays) · **MCP tool:** `list_uploads` · **Notes:** read only

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `kind` | query | `image`, `audio`, `video`, `font`, `all` | optional |  |
| `limit` | query | integer | optional | 1 to 250 |
| `offset` | query | integer | optional | At least 0 |
| `overlayId` | query | string | optional | Optional: the library of this overlay's owner (shared overlays). Up to 64 characters |

::: tabs
@@ cURL
```bash
curl -X GET "https://pxstudio.cloud/api/v1/uploads" \
  -H "Authorization: Bearer $PX_TOKEN"
```
@@ JavaScript
```js
const res = await fetch('https://pxstudio.cloud/api/v1/uploads', {
  headers: {
    Authorization: `Bearer ${process.env.PX_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`PX Studio API: ${res.status}`);
const data = await res.json();
```
:::

### Upload media file

```http Endpoint
POST /api/v1/uploads
```

Uploads one file as the raw request body (Content-Type = the file type: image/png, image/jpeg, image/gif, image/webp, video/mp4, video/webm, audio/*, font/*). Query: name (display name), overlayId (upload into a shared overlay owner's library). Returns the url to use in layer settings. REST only.

**Scope:** `uploads:write` (Upload media) · **MCP tool:** none (REST only)

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `name` | query | string | optional | Up to 120 characters |
| `overlayId` | query | string | optional | Optional: upload for this shared overlay (counts against the owner's storage). Up to 64 characters |

Send the raw file bytes as the request body. The type is detected from the content; SVG is not accepted.

::: tabs
@@ cURL
```bash
curl -X POST "https://pxstudio.cloud/api/v1/uploads" \
  -H "Authorization: Bearer $PX_TOKEN" \
  -H "Content-Type: image/png" \
  --data-binary @logo.png
```
@@ JavaScript
```js
import { readFile } from 'node:fs/promises';

const res = await fetch('https://pxstudio.cloud/api/v1/uploads', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.PX_TOKEN}`,
    'Content-Type': 'image/png',
  },
  body: await readFile('logo.png'),
});
if (!res.ok) throw new Error(`PX Studio API: ${res.status}`);
const data = await res.json();
```
:::

### Delete upload

```http Endpoint
DELETE /api/v1/uploads/{uploadId}
```

DESTRUCTIVE: deletes a file from your media library. A file that a widget still uses answers 409 upload_in_use; send force:true to delete it anyway (the widget then shows nothing there). Owner only. Cannot be undone.

**Scope:** `uploads:write` (Upload media) · **MCP tool:** `delete_upload` · **Notes:** destructive, needs confirmation in MCP

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uploadId` | path | integer | required | Upload id (from list_uploads). At least 1 |
| `force` | query | boolean | optional | Delete even if a widget still uses the file |

::: tabs
@@ cURL
```bash
curl -X DELETE "https://pxstudio.cloud/api/v1/uploads/<uploadId>" \
  -H "Authorization: Bearer $PX_TOKEN"
```
@@ JavaScript
```js
const uploadId = '<uploadId>';

const res = await fetch(`https://pxstudio.cloud/api/v1/uploads/${uploadId}`, {
  method: 'DELETE',
  headers: {
    Authorization: `Bearer ${process.env.PX_TOKEN}`,
  },
});
if (!res.ok) throw new Error(`PX Studio API: ${res.status}`);
const data = await res.json();
```
:::

### Rename upload

```http Endpoint
PATCH /api/v1/uploads/{uploadId}
```

Changes the display name of a file in your media library. Widgets keep using the file. Owner only.

**Scope:** `uploads:write` (Upload media) · **MCP tool:** `rename_upload`

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `uploadId` | path | integer | required | Upload id (from list_uploads). At least 1 |
| `name` | body | string | required | Up to 120 characters |

::: tabs
@@ cURL
```bash
curl -X PATCH "https://pxstudio.cloud/api/v1/uploads/<uploadId>" \
  -H "Authorization: Bearer $PX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "..." }'
```
@@ JavaScript
```js
const uploadId = '<uploadId>';

const res = await fetch(`https://pxstudio.cloud/api/v1/uploads/${uploadId}`, {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.PX_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ name: "..." }),
});
if (!res.ok) throw new Error(`PX Studio API: ${res.status}`);
const data = await res.json();
```
:::
