diff --git a/docs.json b/docs.json
index 5f9adfbd..0b974031 100644
--- a/docs.json
+++ b/docs.json
@@ -365,7 +365,8 @@
"group": "Uploads",
"pages": [
"public-api/uploads/upload-file",
- "public-api/uploads/upload-from-url"
+ "public-api/uploads/upload-from-url",
+ "public-api/uploads/list-media"
]
},
{
diff --git a/mcp/examples.mdx b/mcp/examples.mdx
index ff9f26f8..82949c77 100644
--- a/mcp/examples.mdx
+++ b/mcp/examples.mdx
@@ -226,6 +226,53 @@ API requires Facebook Login.
+## Reuse an Existing Upload
+
+
+
+ The agent calls `mediaListTool`:
+
+ ```json
+ {
+ "search": "launch-banner"
+ }
+ ```
+
+ Returns:
+
+ ```json
+ {
+ "pages": 1,
+ "output": [
+ {
+ "id": "med-789",
+ "name": "6fba0ef5febb4400ae8778a5b854224d.png",
+ "originalName": "launch-banner.png",
+ "path": "https://uploads.postiz.com/6fba0ef5febb4400ae8778a5b854224d.png",
+ "createdAt": "2025-01-10T09:12:00.000Z"
+ }
+ ]
+ }
+ ```
+
+
+ The agent passes the returned `path` as an attachment, no re-upload needed:
+
+ ```json
+ {
+ "postsAndComments": [
+ {
+ "content": "Launch day!
",
+ "attachments": ["https://uploads.postiz.com/6fba0ef5febb4400ae8778a5b854224d.png"]
+ }
+ ]
+ }
+ ```
+
+
+
+---
+
## Generate a Video and Post
diff --git a/mcp/tools.mdx b/mcp/tools.mdx
index 34109506..adc8f0ab 100644
--- a/mcp/tools.mdx
+++ b/mcp/tools.mdx
@@ -234,6 +234,28 @@ If the update fails, returns `{ errors: string }` with details (e.g., post not f
---
+## mediaListTool
+
+List the media files already uploaded to your media library, newest first, 18 per page. Use it to reuse an existing image or video instead of uploading it again.
+
+**Parameters:**
+
+| Field | Type | Required | Description |
+|-------|------|----------|-------------|
+| `search` | string | No | Case-insensitive filter on the original file name |
+| `page` | number | No | Page number, starting at 1 (default 1) |
+
+**Returns:**
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `pages` | number | Total number of pages |
+| `output` | array | Media items: `id`, `name`, `originalName`, `path`, `createdAt` |
+
+Use an item's `path` in the `attachments` array when scheduling a post.
+
+---
+
## generateImageTool
Generate an AI image to use as a post attachment.
diff --git a/public-api/openapi.json b/public-api/openapi.json
index fe355dc6..0e4d0242 100644
--- a/public-api/openapi.json
+++ b/public-api/openapi.json
@@ -1994,6 +1994,74 @@
}
}
},
+ "/media": {
+ "get": {
+ "tags": [
+ "Uploads"
+ ],
+ "summary": "List media",
+ "description": "List the media files already uploaded to your organization's media library, newest first, 18 per page.",
+ "operationId": "listMedia",
+ "parameters": [
+ {
+ "name": "page",
+ "in": "query",
+ "required": false,
+ "description": "Page number (1-indexed). Defaults to 1.",
+ "schema": {
+ "type": "integer",
+ "minimum": 1,
+ "default": 1
+ }
+ },
+ {
+ "name": "search",
+ "in": "query",
+ "required": false,
+ "description": "Case-insensitive filter on the original file name.",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Paginated list of media files",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "pages": {
+ "type": "integer",
+ "description": "Total number of pages"
+ },
+ "results": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/MediaListItem"
+ }
+ }
+ }
+ },
+ "example": {
+ "pages": 2,
+ "results": [
+ {
+ "id": "e639003b-f727-4a1e-87bd-74a2c48ae41e",
+ "name": "6fba0ef5febb4400ae8778a5b854224d.png",
+ "originalName": "cover-cyan.png",
+ "path": "https://uploads.postiz.com/6fba0ef5febb4400ae8778a5b854224d.png",
+ "createdAt": "2024-12-14T08:18:54.274Z"
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/notifications": {
"get": {
"tags": [
@@ -2532,6 +2600,32 @@
}
}
},
+ "MediaListItem": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique file ID"
+ },
+ "name": {
+ "type": "string",
+ "description": "Stored file name"
+ },
+ "originalName": {
+ "type": "string",
+ "nullable": true,
+ "description": "File name as uploaded (searchable)"
+ },
+ "path": {
+ "type": "string",
+ "description": "Public file URL, usable as a post attachment"
+ },
+ "createdAt": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ },
"MediaFile": {
"type": "object",
"properties": {
diff --git a/public-api/uploads/list-media.mdx b/public-api/uploads/list-media.mdx
new file mode 100644
index 00000000..45d25a16
--- /dev/null
+++ b/public-api/uploads/list-media.mdx
@@ -0,0 +1,38 @@
+---
+title: 'List Media'
+openapi: 'GET /media'
+icon: 'images'
+---
+
+List the files already in your media library so you can reuse them as post attachments without uploading again. Results are scoped to your organization, sorted newest first, 18 per page.
+
+## Query parameters
+
+- `page`: page number, starting at 1 (default 1).
+- `search`: case-insensitive filter on the original file name.
+
+## Example
+
+```bash
+curl "https://api.postiz.com/public/v1/media?search=banner&page=1" \
+ -H "Authorization: your-api-key"
+```
+
+Response:
+
+```json
+{
+ "pages": 1,
+ "results": [
+ {
+ "id": "e639003b-f727-4a1e-87bd-74a2c48ae41e",
+ "name": "6fba0ef5febb4400ae8778a5b854224d.png",
+ "originalName": "launch-banner.png",
+ "path": "https://uploads.postiz.com/6fba0ef5febb4400ae8778a5b854224d.png",
+ "createdAt": "2025-01-10T09:12:00.000Z"
+ }
+ ]
+}
+```
+
+Pass an item's `path` in a post's `image` array (see [Create Post](/public-api/posts/create)). `path` is a public URL, so there is no separate download endpoint.