Reserve media upload

Creates a media library row and returns a presigned upload URL for local files or raw bytes. Hosted public URLs do not need this step; send them directly in platform_posts[].media_urls on POST/v1/posts. After the PUT succeeds, poll GET/v1/media/:media_id until status is uploaded before using the media ID in POST/v1/posts.
https://api.unipost.dev
POST/v1/media
Authorization
In header · Bearer <token>
Request Body
string
string

Authorization

AuthorizationBearer <token>In header
Workspace API key.

Request Body

filenamestring
Original file name for the asset.
content_typestring
MIME type such as image/jpeg, video/mp4, or audio/mpeg. Audio uploads are accepted as media-processing inputs; publish the processed video output, not the raw audio media ID.
size_bytesOptionalnumber
Optional upload size in bytes. If provided, it must be greater than 0. If your client does not know the byte length yet, omit size_bytes; UniPost hydrates the actual size from storage after upload. If the asset already has a public URL, skip POST/v1/media and send that URL in platform_posts[].media_urls on POST/v1/posts.

Response Body

200
media_idstring
Media library ID to use in later publish calls.
upload_urlstring
Presigned storage URL for the raw file bytes.
statusstring
Media lifecycle state. Reserve responses start as pending; publish calls should wait for uploaded.
Valuespending | uploaded | attached | deleted
201
media_idstring
Media library ID to use in later publish calls.
upload_urlstring
Presigned storage URL for the raw file bytes.
statusstring
Media lifecycle state. Reserve responses start as pending; publish calls should wait for uploaded.
Valuespending | uploaded | attached | deleted
401
error.codestring
Usually "UNAUTHORIZED".
error.normalized_codestring
Lowercase alias such as "unauthorized".
error.messagestring
Human-readable error message.
request_idstring
Request identifier for debugging and support.
422
error.codestring
Usually "UNAUTHORIZED".
error.normalized_codestring
Lowercase alias such as "unauthorized".
error.messagestring
Human-readable error message.
request_idstring
Request identifier for debugging and support.
500
error.codestring
Usually "UNAUTHORIZED".
error.normalized_codestring
Lowercase alias such as "unauthorized".
error.messagestring
Human-readable error message.
request_idstring
Request identifier for debugging and support.
503
error.codestring
Usually "UNAUTHORIZED".
error.normalized_codestring
Lowercase alias such as "unauthorized".
error.messagestring
Human-readable error message.
request_idstring
Request identifier for debugging and support.
Size is optional: clients no longer need to calculate file length before reserving an upload. When size_bytes is omitted, the pending media response can show size_bytes: 0;GET/v1/media/:media_id returns the hydrated size after the PUT lands.
Retention follows post status: UniPost keeps uploaded media for scheduled, draft, queued, publishing, and processing posts. After the parent post finishes, media is retained by plan: Free 1 day after success or 2 days after failed/partial/cancelled, API 2/4 days, Basic 4/8 days, Growth 15/30 days, and Team 30/60 days. Reused media is deleted only after all post usages are due.
TikTok file_upload note: upload the complete video file to UniPost with this endpoint, then publish with media_ids. UniPost handles TikTok's downstream chunk sizing and sequential transfer automatically, including videos larger than 64 MB. Do not split the file or provide TikTok chunk_size / total_chunk_count yourself.