Media
Upload images or videos that posts will reference. Small files can go directly with multipart; for large files, request a presigned URL and upload straight to storage. You can also hand us a public HTTPS URL and we'll fetch it, which is useful for agents that have already generated or stored media elsewhere.
Upload via multipart
/api/v1/mediacurl -X POST https://postme.live/api/v1/media \
-H "Authorization: Bearer pml_live_..." \
-H "Idempotency-Key: $(uuidgen)" \
-F "[email protected]"Upload via URL
/api/v1/mediacurl -X POST https://postme.live/api/v1/media \
-H "Authorization: Bearer pml_live_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/hero.jpg" }'URLs must be https://, resolve to a public IP (no private, loopback, link-local, or ULA addresses), and download in under 5 minutes for files no larger than 1 GB.
Upload large files with a presigned URL
Multipart streams the bytes through the API and is best for small files. For large media, ask for a presigned PUT URL, send the bytes straight to storage, then register the object. Three steps:
/api/v1/media/upload-url# 1. Request a presigned PUT URL
curl -X POST https://postme.live/api/v1/media/upload-url \
-H "Authorization: Bearer pml_live_..." \
-H "Content-Type: application/json" \
-d '{ "filename": "clip.mp4", "content_type": "video/mp4", "size": 73400320 }'
# → { "upload_url": "https://…", "key": "…", "expires_in": 600 }
# 2. PUT the bytes straight to storage (same Content-Type)
curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: video/mp4" \
--data-binary @clip.mp4
# 3. Register the uploaded object
curl -X POST https://postme.live/api/v1/media \
-H "Authorization: Bearer pml_live_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "key": "<key from step 1>" }'The presigned URL is valid for 10 minutes and accepts exactly the content_type you declared. Step 3 returns the same 201 Created body as the other methods and is where plan caps are enforced against the real object size. Requesting the URL is not a billable write, so it needs no Idempotency-Key; step 3 does.
Agents on the MCP server run this exact flow with the postmelive_create_media_upload and postmelive_upload_media tools — the way to attach a local file that isn't already at a public URL.
Response: 201 Created
{
"id": "9f3a…",
"kind": "image",
"bytes": 184320,
"mime": "image/jpeg",
"filename": "hero.jpg",
"url": "https://media.postme.live/…",
"thumbnail_status": "pending"
}Use the returned id in media[].id on a subsequent POST /posts. Thumbnail generation, ffprobe metadata extraction, and YouTube poster- frame candidates run asynchronously on the worker; the post endpoint doesn't wait for them.
List media
/api/v1/mediaLists the workspace's media library, newest first, cursor-paginated. Filter by ?kind=image or ?kind=video (any other value is a 400). Scope media:read.
curl "https://postme.live/api/v1/media?kind=image&limit=50" \
-H "Authorization: Bearer pml_live_..."Response: 200 OK
{
"data": [
{
"id": "9f3a4b2c-6d7e-4a1b-8c9d-0e1f2a3b4c5d",
"kind": "image",
"mime": "image/jpeg",
"bytes": 184320,
"width": 1080,
"height": 1350,
"duration_ms": null,
"filename": "hero.jpg",
"url": "https://media.postme.live/…",
"thumbnail_status": "ready",
"thumbnails": {
"thumb": { "url": "https://media.postme.live/…", "width": 320, "height": 400 },
"preview": { "url": "https://media.postme.live/…", "width": 640, "height": 800 },
"display": { "url": "https://media.postme.live/…", "width": 1080, "height": 1350 }
},
"created_at": "2026-06-27T14:02:11Z"
}
],
"has_more": false,
"next_cursor": null
}The list returns the full media record, including width/ height, duration_ms (videos), the generated thumbnails set, and created_at. Any of those is null until the worker has processed the asset (watch thumbnail_status).
Get a media item
/api/v1/media/{id}A single media item, shaped exactly like one element of the list above (not wrapped in data). Media in another workspace reads as 404. Scope media:read.
curl https://postme.live/api/v1/media/9f3a4b2c-6d7e-4a1b-8c9d-0e1f2a3b4c5d \
-H "Authorization: Bearer pml_live_..."Limits
| Limit | Value |
|---|---|
| Maximum file size | 1 GB (bounded by your plan's per-file cap) |
| Multipart request size | Up to 16 MB; use a presigned URL or url fetch for larger files |
| Presigned URL lifetime | 10 minutes |
| URL fetch timeout | 5 minutes |
| Allowed URL schemes | https:// |
| Allowed remote networks | Public IPs only (no private/loopback/link-local/ULA) |