Media
The brand's media library.
These endpoints ignore X-Postlyra-Brand
Media reads your currently-selected brand, not the header. Call PATCH /me/team first to target a specific brand. See Choosing a brand.
GET /media
{
"media": [
{
"id": 91,
"file_name": "slide-1.jpg",
"name": "slide-1",
"mime_type": "image/jpeg",
"size": 184320,
"url": "https://cdn.postlyra.com/91/slide-1.jpg",
"caption": null,
"alt_text": null,
"created_at": "2026-08-14T10:04:11.000000Z"
}
]
}POST /media
Multipart upload, field name file.
curl -X POST https://api.postlyra.com/media \
-H "Authorization: Bearer $POSTLYRA_TOKEN" \
-F "file=@slide-1.jpg"Returns 201 with the media object.
| Limit | Value |
|---|---|
| Max file size | 10 MB |
| Total storage | Your plan's storage_limit, in GB |
Exceeding your storage allowance returns 422:
{ "message": "Storage limit reached. Free up space or upgrade your plan to upload more." }DELETE /media/{id}
{ "message": "Deleted." }The URLs are public
Media is world-readable
Media is served from a public CDN bucket. Anyone with the URL can fetch a file, with no authentication, and ids are sequential.
This is not a misconfiguration. Instagram and the other Graph APIs will only accept media as a public HTTPS URL, so the file has to be reachable for publishing to work at all.
Never upload anything you would not publish.
Video
Video does not go through these endpoints. Video assets upload directly from the browser to storage in parts, then get probed and validated against each platform's requirements. That flow lives in the draft composer in Studio. See Video uploads.