Media
- get/v1/media
- post/v1/media
- get/v1/media/{id}
- del/v1/media/{id}
- post/v1/media/{id}/complete
- get/v1/media-folders
- post/v1/media-folders
- patch/v1/media-folders/{id}
- del/v1/media-folders/{id}
- post/v1/media-folders/{id}/move
- put/v1/media-folder-colors
- post/v1/media-moves
- put/v1/media/{id}/title
- put/v1/media/{id}/alt-text
- get/v1/media/{id}/usage
- get/v1/media-storage
List media
get/v1/media
List media assets in the selected workspace with optional status and content-type filters and cursor pagination. Returns media IDs, metadata and temporary signed download URLs. Use ready media IDs when attaching assets to posts.
Query parameters
workspaceIdstringMin length 1
limitintegerDefault 20 · Min 1 · Max 100
starting_afterstringending_beforestringstatusstringOne of
pendingprocessingreadyfaileddedupedcontentTypestringOne of
image/jpegimage/pngimage/webpimage/gifvideo/mp4video/quicktime
Response 200
List of media
objectstringrequiredOne of
listhas_morebooleanrequirednext_cursorstringrequirednullable
Errors
- 401
- Unauthenticated
- 403
- Missing scope
curl "https://api.posty.social/v1/media" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"object": "list",
"data": [
{
"id": "string",
"workspaceId": "string",
"folderId": "string",
"title": "string",
"thumbhash": "string",
"sizeBytes": 1,
"contentType": "string",
"etag": "string",
"status": "pending",
"width": 1,
"height": 1,
"altText": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"duration": 1,
"url": "string",
"thumbnailUrl": "string"
}
],
"has_more": true,
"next_cursor": "string"
}Create media upload
post/v1/media
Start a media upload by providing a title, supported contentType and sizeBytes in the selected workspace. Creates a pending media record and returns its ID, temporary uploadUrl and expiry. Transfer file bytes separately with HTTP PUT to uploadUrl, then call complete_media_upload. This call alone does not transfer the file.
Request body
titlestringrequiredMin length 1 · Max length 500
contentTypestringrequiredOne of
image/jpegimage/pngimage/webpimage/gifvideo/mp4video/quicktimesizeBytesintegerrequiredMin 1 · Max 5000000000
Response 201
Upload URL issued
idstringrequireduploadUrlstringrequiredkeystringrequiredexpiresAtstring (date-time)required
Errors
- 400
- Validation error
- 401
- Unauthenticated
- 403
- Missing scope
- 409
- Storage limit exceeded
curl -X POST "https://api.posty.social/v1/media" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "string",
"contentType": "image/jpeg",
"sizeBytes": 1
}'{
"id": "string",
"uploadUrl": "string",
"key": "string",
"expiresAt": "2026-01-15T09:30:00.000Z"
}Get media
get/v1/media/{id}
Retrieve a media asset by ID in the selected workspace. Returns its upload or processing status, file metadata and temporary signed download URLs for the asset and any thumbnail.
Path parameters
idstringrequired
Response 200
Media
idstringrequiredworkspaceIdstringrequiredfolderIdstringrequirednullabletitlestringrequiredthumbhashstringrequirednullableBase64 ThumbHash (https://evanw.github.io/thumbhash/) of the thumbnail, for a blurred placeholder while it loads. Null until one has been computed.
sizeBytesintegerrequiredcontentTypestringrequiredetagstringrequirednullablestatusstringrequiredOne of
pendingprocessingreadyfaileddedupedwidthintegerrequirednullableheightintegerrequirednullablealtTextstringrequirednullablecreatedAtstring (date-time)requirednullableupdatedAtstring (date-time)requirednullabledurationintegerrequirednullableurlstringrequirednullablethumbnailUrlstringrequirednullable
Errors
- 401
- Unauthenticated
- 403
- Missing scope
- 404
- Not found
curl "https://api.posty.social/v1/media/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"id": "string",
"workspaceId": "string",
"folderId": "string",
"title": "string",
"thumbhash": "string",
"sizeBytes": 1,
"contentType": "string",
"etag": "string",
"status": "pending",
"width": 1,
"height": 1,
"altText": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"duration": 1,
"url": "string",
"thumbnailUrl": "string"
}Delete media
del/v1/media/{id}
Remove a media asset from the selected workspace library by ID. Hides it from library listings while preserving stored files and existing post attachments. Returns a deletion confirmation.
Path parameters
idstringrequired
Response 204
Deleted
Errors
- 401
- Unauthenticated
- 403
- Missing scope
- 404
- Not found
curl -X DELETE "https://api.posty.social/v1/media/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY"No contentComplete media upload
post/v1/media/{id}/complete
Finalize a media upload after transferring its file bytes to the signed upload URL. Provide the media ID and optional dimensions or duration. Checks the uploaded object and storage quota, then returns finalized media metadata. Missing uploads or exceeded quotas produce errors.
Path parameters
idstringrequired
Request body
etagstringwidthintegerheightintegerdurationinteger
Response 200
Media finalized (or already finalized)
idstringrequiredworkspaceIdstringrequiredfolderIdstringrequirednullabletitlestringrequiredthumbhashstringrequirednullableBase64 ThumbHash (https://evanw.github.io/thumbhash/) of the thumbnail, for a blurred placeholder while it loads. Null until one has been computed.
sizeBytesintegerrequiredcontentTypestringrequiredetagstringrequirednullablestatusstringrequiredOne of
pendingprocessingreadyfaileddedupedwidthintegerrequirednullableheightintegerrequirednullablealtTextstringrequirednullablecreatedAtstring (date-time)requirednullableupdatedAtstring (date-time)requirednullabledurationintegerrequirednullableurlstringrequirednullablethumbnailUrlstringrequirednullable
Errors
- 401
- Unauthenticated
- 403
- Missing scope
- 404
- Not found
curl -X POST "https://api.posty.social/v1/media/$ID/complete" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"etag": "string",
"width": 1,
"height": 1,
"duration": 1
}'{
"id": "string",
"workspaceId": "string",
"folderId": "string",
"title": "string",
"thumbhash": "string",
"sizeBytes": 1,
"contentType": "string",
"etag": "string",
"status": "pending",
"width": 1,
"height": 1,
"altText": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"duration": 1,
"url": "string",
"thumbnailUrl": "string"
}List media folders
get/v1/media-folders
List every media library folder in the workspace as a flat tree (parentId null is top level), with file counts. Needs media:view.
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl "https://api.posty.social/v1/media-folders" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"data": [
{
"id": "string",
"parentId": "string",
"name": "string",
"color": "red",
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"mediaCount": 1
}
]
}Create media folder
post/v1/media-folders
Create a media library folder, at the top level or inside parentId. Sibling names must be unique. Needs media:upload.
Request body
namestringrequiredMin length 1 · Max length 120 · Pattern ^[^/]*$
parentIdstringnullableMin length 1
Response 201
Folder created
idstringrequiredparentIdstringrequirednullablenamestringrequiredcolorstringrequirednullableOne of
redorangeyellowgreenbluepurplegreycreatedBystringrequirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)requiredmediaCountintegerFiles directly in this folder. Present on list and create.
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X POST "https://api.posty.social/v1/media-folders" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"parentId": "string"
}'{
"id": "string",
"parentId": "string",
"name": "string",
"color": "red",
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"mediaCount": 1
}Rename media folder
patch/v1/media-folders/{id}
Rename a media library folder. The new name must be unique among its siblings. Needs media:upload.
Path parameters
idstringrequiredMin length 1
Request body
namestringrequiredMin length 1 · Max length 120 · Pattern ^[^/]*$
Response 200
Folder renamed
idstringrequiredparentIdstringrequirednullablenamestringrequiredcolorstringrequirednullableOne of
redorangeyellowgreenbluepurplegreycreatedBystringrequirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)requiredmediaCountintegerFiles directly in this folder. Present on list and create.
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X PATCH "https://api.posty.social/v1/media-folders/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string"
}'{
"id": "string",
"parentId": "string",
"name": "string",
"color": "red",
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"mediaCount": 1
}Delete media folder
del/v1/media-folders/{id}
Delete a folder, its subfolders, and remove every file inside them from the library. Files already attached to posts stay on those posts. Needs media:delete.
Path parameters
idstringrequiredMin length 1
Response 204
Folder deleted
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X DELETE "https://api.posty.social/v1/media-folders/$ID" \
-H "Authorization: Bearer $POSTY_API_KEY"No contentMove media folder
post/v1/media-folders/{id}/move
Move a folder, with everything in it, under parentId or to the top level with null. A folder cannot move into itself or its descendants. Needs media:upload.
Path parameters
idstringrequiredMin length 1
Request body
parentIdstringrequirednullableMin length 1
Response 200
Folder moved
idstringrequiredparentIdstringrequirednullablenamestringrequiredcolorstringrequirednullableOne of
redorangeyellowgreenbluepurplegreycreatedBystringrequirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)requiredmediaCountintegerFiles directly in this folder. Present on list and create.
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X POST "https://api.posty.social/v1/media-folders/$ID/move" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"parentId": "string"
}'{
"id": "string",
"parentId": "string",
"name": "string",
"color": "red",
"createdBy": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"mediaCount": 1
}Set media folder color
put/v1/media-folder-colors
Tag up to 200 folders with one colour, or clear it with null. All or nothing: an unknown folder id fails the whole change. Needs media:upload.
Request body
folderIdsarray of stringrequiredMin items 1 · Max items 200
colorstringrequirednullableOne of
redorangeyellowgreenbluepurplegrey
Response 200
Folders updated
folderIdsarray of stringrequired
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X PUT "https://api.posty.social/v1/media-folder-colors" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"folderIds": [
"string"
],
"color": "red"
}'{
"folderIds": [
"string"
]
}Move media items
post/v1/media-moves
Move up to 200 library files into folderId, or to the top level with null. All or nothing: an unknown media id fails the whole move. Needs media:upload.
Request body
mediaIdsarray of stringrequiredMin items 1 · Max items 200
folderIdstringrequirednullableMin length 1
Response 200
Files moved
movedintegerrequired
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X POST "https://api.posty.social/v1/media-moves" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mediaIds": [
"string"
],
"folderId": "string"
}'{
"moved": 1
}Rename media
put/v1/media/{id}/title
Rename a library file (its display title, up to 500 characters). Needs media:upload.
Path parameters
idstringrequiredMin length 1
Request body
titlestringrequiredMin length 1 · Max length 500
Response 200
Renamed file
idstringrequiredworkspaceIdstringrequiredfolderIdstringrequirednullabletitlestringrequiredthumbhashstringrequirednullableBase64 ThumbHash (https://evanw.github.io/thumbhash/) of the thumbnail, for a blurred placeholder while it loads. Null until one has been computed.
sizeBytesintegerrequiredcontentTypestringrequiredetagstringrequirednullablestatusstringrequiredOne of
pendingprocessingreadyfaileddedupedwidthintegerrequirednullableheightintegerrequirednullablealtTextstringrequirednullablecreatedAtstring (date-time)requirednullableupdatedAtstring (date-time)requirednullabledurationintegerrequirednullableurlstringrequirednullablethumbnailUrlstringrequirednullable
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X PUT "https://api.posty.social/v1/media/$ID/title" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "string"
}'{
"id": "string",
"workspaceId": "string",
"folderId": "string",
"title": "string",
"thumbhash": "string",
"sizeBytes": 1,
"contentType": "string",
"etag": "string",
"status": "pending",
"width": 1,
"height": 1,
"altText": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"duration": 1,
"url": "string",
"thumbnailUrl": "string"
}Set media alt text
put/v1/media/{id}/alt-text
Set the accessibility description published with this file on platforms that support alt text, or clear it with null or an empty string. Up to 1000 characters. Needs media:upload.
Path parameters
idstringrequiredMin length 1
Request body
altTextstringrequirednullableMax length 1000
Response 200
File with its alt text
idstringrequiredworkspaceIdstringrequiredfolderIdstringrequirednullabletitlestringrequiredthumbhashstringrequirednullableBase64 ThumbHash (https://evanw.github.io/thumbhash/) of the thumbnail, for a blurred placeholder while it loads. Null until one has been computed.
sizeBytesintegerrequiredcontentTypestringrequiredetagstringrequirednullablestatusstringrequiredOne of
pendingprocessingreadyfaileddedupedwidthintegerrequirednullableheightintegerrequirednullablealtTextstringrequirednullablecreatedAtstring (date-time)requirednullableupdatedAtstring (date-time)requirednullabledurationintegerrequirednullableurlstringrequirednullablethumbnailUrlstringrequirednullable
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl -X PUT "https://api.posty.social/v1/media/$ID/alt-text" \
-H "Authorization: Bearer $POSTY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"altText": "string"
}'{
"id": "string",
"workspaceId": "string",
"folderId": "string",
"title": "string",
"thumbhash": "string",
"sizeBytes": 1,
"contentType": "string",
"etag": "string",
"status": "pending",
"width": 1,
"height": 1,
"altText": "string",
"createdAt": "2026-01-15T09:30:00.000Z",
"updatedAt": "2026-01-15T09:30:00.000Z",
"duration": 1,
"url": "string",
"thumbnailUrl": "string"
}Get media usage
get/v1/media/{id}/usage
List the posts and channels a library file is attached to, limited to posts the caller can see. Needs media:view.
Path parameters
idstringrequiredMin length 1
Response 200
Where the file is used
dataarray of objectrequiredChild attributes
postIdstringrequiredpostContentIdstringrequiredpostStatusstringrequiredOne of
draftpending_approvalpending_client_approvalapprovedscheduleddeliveredpartially_delivereddelivery_failedplatformstringrequiredOne of
blueskydiscordfacebookinstagramlinkedinpinterestthreadstiktokwordpressyoutubebodystringrequirednullable
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl "https://api.posty.social/v1/media/$ID/usage" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"data": [
{
"postId": "string",
"postContentId": "string",
"postStatus": "draft",
"platform": "bluesky",
"body": "string"
}
]
}Get storage usage
get/v1/media-storage
Bytes the media library uses against the workspace plan's storage limit, and how many remain. limitBytes and remainingBytes are null on an unlimited plan. Needs media:view.
Response 200
Storage usage
usedBytesintegerrequiredlimitBytesintegerrequirednullableremainingBytesintegerrequirednullableunlimitedbooleanrequired
Errors
- 400
- Invalid request
- 403
- Missing permission
- 404
- Media or folder not found
- 409
- Name taken, cycle, or uploads still in progress
curl "https://api.posty.social/v1/media-storage" \
-H "Authorization: Bearer $POSTY_API_KEY"{
"usedBytes": 1,
"limitBytes": 1,
"remainingBytes": 1,
"unlimited": true
}Models
Objects referenced by the endpoints above.
Media
idstringrequiredworkspaceIdstringrequiredfolderIdstringrequirednullabletitlestringrequiredthumbhashstringrequirednullableBase64 ThumbHash (https://evanw.github.io/thumbhash/) of the thumbnail, for a blurred placeholder while it loads. Null until one has been computed.
sizeBytesintegerrequiredcontentTypestringrequiredetagstringrequirednullablestatusstringrequiredOne of
pendingprocessingreadyfaileddedupedwidthintegerrequirednullableheightintegerrequirednullablealtTextstringrequirednullablecreatedAtstring (date-time)requirednullableupdatedAtstring (date-time)requirednullabledurationintegerrequirednullableurlstringrequirednullablethumbnailUrlstringrequirednullable
MediaFolder
idstringrequiredparentIdstringrequirednullablenamestringrequiredcolorstringrequirednullableOne of
redorangeyellowgreenbluepurplegreycreatedBystringrequirednullablecreatedAtstring (date-time)requiredupdatedAtstring (date-time)requiredmediaCountintegerFiles directly in this folder. Present on list and create.