From ea142a460589637a4a8971954374d5721546890b Mon Sep 17 00:00:00 2001 From: Gilad Resisi Date: Wed, 19 Aug 2026 18:34:47 +0700 Subject: [PATCH 1/2] docs: list media via public API (GET /media) and MCP mediaListTool Documents gitroomhq/postiz-app#1926: OpenAPI entry for GET /public/v1/media, a List Media page under Uploads, mediaListTool in the MCP tools reference and a "reuse an existing upload" example. Verified with mintlify dev: all three pages render with correct navigation entries and no overflow. Co-Authored-By: Claude Fable 5 --- docs.json | 3 +- mcp/examples.mdx | 50 +++++++++++++ mcp/tools.mdx | 22 ++++++ public-api/openapi.json | 120 ++++++++++++++++++++++++++++++ public-api/uploads/list-media.mdx | 43 +++++++++++ 5 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 public-api/uploads/list-media.mdx diff --git a/docs.json b/docs.json index 529b9800..b6331418 100644 --- a/docs.json +++ b/docs.json @@ -359,7 +359,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 580c5e53..5d84b5a3 100644 --- a/mcp/examples.mdx +++ b/mcp/examples.mdx @@ -226,6 +226,56 @@ 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", + "type": "image", + "fileSize": 48213, + "createdAt": "2025-01-10T09:12:00.000Z", + "thumbnail": null + } + ] + } + ``` + + + 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 fd9049aa..88885b82 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`, `type`, `fileSize`, `createdAt`, `thumbnail` | + +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 21629023..7fa245c8 100644 --- a/public-api/openapi.json +++ b/public-api/openapi.json @@ -1990,6 +1990,79 @@ } } }, + "/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", + "thumbnail": null, + "alt": null, + "thumbnailTimestamp": null, + "type": "image", + "fileSize": 48213, + "createdAt": "2024-12-14T08:18:54.274Z" + } + ] + } + } + } + } + } + } + }, "/notifications": { "get": { "tags": [ @@ -2282,6 +2355,53 @@ } } }, + "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" + }, + "thumbnail": { + "type": "string", + "nullable": true, + "description": "Thumbnail URL (videos)" + }, + "alt": { + "type": "string", + "nullable": true + }, + "thumbnailTimestamp": { + "type": "integer", + "nullable": true + }, + "type": { + "type": "string", + "description": "image or video" + }, + "fileSize": { + "type": "integer", + "description": "Size in bytes" + }, + "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..93e224fc --- /dev/null +++ b/public-api/uploads/list-media.mdx @@ -0,0 +1,43 @@ +--- +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", + "thumbnail": null, + "alt": null, + "thumbnailTimestamp": null, + "type": "image", + "fileSize": 48213, + "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. From 5fc99df972371edf7b5ef2747b2247f12b28c6b8 Mon Sep 17 00:00:00 2001 From: Gilad Resisi Date: Wed, 19 Aug 2026 22:36:41 +0700 Subject: [PATCH 2/2] docs: describe the media type field accurately Co-Authored-By: Claude Fable 5 --- public-api/openapi.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public-api/openapi.json b/public-api/openapi.json index 7fa245c8..0a107b73 100644 --- a/public-api/openapi.json +++ b/public-api/openapi.json @@ -2390,7 +2390,7 @@ }, "type": { "type": "string", - "description": "image or video" + "description": "Media type. Currently always \"image\" regardless of the file; use the extension of path to tell images from videos." }, "fileSize": { "type": "integer",