Create media upload
Upload a file of up to 4 GB (500 MB on the Free plan) straight to storage:
- Call this endpoint with
filename,contentTypeandfileSize. You get back anidand anuploadUrl. PUTthe file touploadUrlwith the sameContent-Typeheader. Storage answers200, or403if the file is not exactlyfileSizebytes.- Optional: call Complete media upload to add the file to your media library now.
- Put the
idinmediaIdswhen you create or update a post.
Authorization
ApiKeyAuth PublishQ API key sent as Authorization: Bearer pq_live_....
In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://publishq.com/api/v1/media/uploads" \ -H "Content-Type: application/json" \ -d '{ "filename": "launch-video.mp4", "contentType": "video/mp4", "fileSize": 262144000 }'{
"id": "f6370ca1-1f47-4f68-be72-c1206913b326",
"uploadUrl": "https://s3.us-east-1.amazonaws.com/...?X-Amz-Signature=...",
"expiresAt": "2026-10-21T15:36:39.000Z"
}{
"error": {
"title": "Bad Request",
"status": 400,
"code": "validation_failed",
"message": "Request validation failed",
"instance": "/api/v1/media",
"details": {
"errors": [
{
"path": "mediaTypes.0",
"message": "Invalid option: expected one of \"IMAGE\"|\"VIDEO\"",
"code": "invalid_value"
}
]
}
}
}{
"error": {
"title": "Unauthorized",
"status": 401,
"code": "missing_auth",
"message": "Missing Authorization header",
"instance": "/api/v1/posts"
}
}{
"error": {
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"message": "The API key does not have the required scope: posts:write",
"instance": "/api/v1/posts",
"details": {
"property1": {},
"property2": {}
}
}
}{
"error": {
"title": "Forbidden",
"status": 403,
"code": "insufficient_scope",
"message": "Missing required scope: media:write",
"instance": "/api/v1/media/uploads"
}
}{
"error": {
"title": "Payload Too Large",
"status": 413,
"code": "file_too_large",
"message": "File size too large. Free accounts can upload files up to 500 MB. Upgrade to upload files up to 4 GB.",
"instance": "/api/v1/media"
}
}{
"error": {
"title": "Unsupported Media Type",
"status": 415,
"code": "unsupported_file_type",
"message": "Unsupported file type: the file content is audio/mpeg, even though it is labelled video/mp4. Renaming a file does not change its format. Supported types: image/jpeg, image/png, image/gif, image/webp, video/mp4, video/webm, video/quicktime, video/x-msvideo.",
"instance": "/api/v1/media"
}
}{
"error": {
"title": "Too Many Requests",
"status": 429,
"code": "rate_limit_exceeded",
"message": "Too Many Requests",
"instance": "/api/v1/media/uploads",
"details": {
"retryAfter": 60
}
}
}Upload media POST
Upload a file smaller than 100 MB in a single request. It is the simplest way to upload: one call returns a media ID you can attach to posts. For bigger files, use Create media upload.
Complete media upload POST
Optional. Adds a file uploaded through Create media upload to your media library now and returns it. Without this call the file is added the first time you use its id in a post, and an upload nobody completes or uses within 1 day expires.