Skip to main content
This endpoint requires a valid Bearer token.

Endpoint

POST /api/posts/media/upload

How pre-signed upload URLs work

Hayon does not proxy file uploads through its own servers. Instead, it issues a temporary pre-signed URL that grants your client direct write access to the S3 bucket for a single object.
1

Request a pre-signed URL

Call POST /api/posts/media/upload with the contentType of the file you want to upload. The server returns a short-lived uploadUrl, the permanent public s3Url, and the s3Key.
2

Upload the file directly to S3

Make a PUT request to the uploadUrl with the file as the request body and the Content-Type header set to the same MIME type you specified. No authentication header is needed for this request — the signature is embedded in the URL.
3

Reference s3Url in your post

Use the returned s3Url and s3Key in the content.mediaItems array when calling Create Post or Update Post.

Request body

contentType
string
required
MIME type of the file to upload. Accepted values:
  • image/png
  • image/jpeg
  • image/jpg
  • image/webp
  • video/mp4
  • video/quicktime

Response

success
boolean
required
true on success.
message
string
required
"Upload URL generated"
data
object
required

Examples

curl --request POST \
  --url 'https://api.hayon.app/api/posts/media/upload' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{"contentType": "image/png"}'

Example response — Step 1

200
{
  "success": true,
  "message": "Upload URL generated",
  "data": {
    "uploadUrl": "https://hayon-media.s3.amazonaws.com/posts/user123/post-media.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
    "s3Url": "https://cdn.hayon.app/posts/user123/post-media.png",
    "s3Key": "posts/user123/post-media.png",
    "contentType": "image/png"
  }
}
The uploadUrl contains an AWS signature and expires after a short window. Do not cache it for later use — generate a new URL for each upload.

Error responses

400 Unsupported media type
{
  "success": false,
  "message": "Invalid media type"
}

Build docs developers (and LLMs) love