Skip to main content

Media API

The Media API lets you upload remote media files to the Soku media library and render OG template images. Once uploaded, the returned URL can be used in post submissions for video and image content.

Upload Remote Media

Download a media file from a remote URL and store it in the Soku media library.
POST /v1/media

Authentication

This endpoint uses API key authentication. Include your API key in the soku-api-key header. An active Soku subscription (trialing or active) is required.

Headers

HeaderRequiredDescription
Content-TypeYesMust be application/json
soku-api-keyYesYour Soku API key
Idempotency-KeyNoA unique string to prevent duplicate uploads. If omitted, Soku auto-derives a key from your user ID and request payload.

Rate Limit

30 requests per 60 seconds, in addition to the global tier limit. See Rate Limits.

Request Body

FieldTypeRequiredDescription
urlstringYesThe publicly accessible URL of the media file to upload. Must be a valid HTTP or HTTPS URL.

Response

Status: 201 Created
FieldTypeDescription
urlstringThe Soku-hosted URL of the uploaded media file. Use this URL in the mediaUrls, videoUrl, or imageUrls fields when creating posts.
{
  "url": "https://storage.mysoku.io/media/a1b2c3d4/uploaded-file.mp4"
}

Render OG Template Image

Render an OG image template. This is an alias for POST /v1/templates and is functionally identical.
POST /v1/media/render-og

Authentication

This endpoint uses API key authentication. Include your API key in the soku-api-key header. An active Soku subscription (trialing or active) is required.

Rate Limit

20 requests per 60 seconds, in addition to the global tier limit. See Rate Limits.
For full documentation on template rendering including request body, config options, and examples, see the Templates API.

Examples

Upload a video from a remote URL

curl -X POST https://api.mysoku.io/v1/media \
  -H "Content-Type: application/json" \
  -H "soku-api-key: sk_live_your_api_key_here" \
  -d '{
    "url": "https://example.com/videos/product-demo.mp4"
  }'
Response:
{
  "url": "https://storage.mysoku.io/media/f7e8d9c0/product-demo.mp4"
}

Upload an image

curl -X POST https://api.mysoku.io/v1/media \
  -H "Content-Type: application/json" \
  -H "soku-api-key: sk_live_your_api_key_here" \
  -d '{
    "url": "https://example.com/images/banner.png"
  }'
Response:
{
  "url": "https://storage.mysoku.io/media/b3c4d5e6/banner.png"
}

Upload and then publish

A common workflow is to upload media first, then use the returned URL in a post:
# Step 1: Upload the media
MEDIA_URL=$(curl -s -X POST https://api.mysoku.io/v1/media \
  -H "Content-Type: application/json" \
  -H "soku-api-key: sk_live_your_api_key_here" \
  -d '{"url": "https://example.com/videos/demo.mp4"}' \
  | jq -r '.url')

# Step 2: Create a post using the uploaded media
curl -X POST https://api.mysoku.io/v1/posts \
  -H "Content-Type: application/json" \
  -H "soku-api-key: sk_live_your_api_key_here" \
  -d "{
    \"post\": {
      \"content\": {
        \"text\": \"Check out our latest demo\",
        \"mediaType\": \"video\",
        \"videoUrl\": \"$MEDIA_URL\",
        \"platform\": [\"instagram\", \"tiktok\", \"youtube\"]
      }
    }
  }"

Supported Media Formats

The Media API accepts any media file that the source URL serves over HTTP or HTTPS. For best results with social platform publishing, use the following formats:
TypeRecommended FormatsNotes
VideoMP4 (H.264)Most universally supported across all platforms
ImageJPEG, PNG, WebPJPEG recommended for photos, PNG for graphics
For detailed information on media format requirements and file size limits per platform, see Media Formats & Limits.

Idempotency

The Idempotency-Key header prevents duplicate uploads when retrying requests.
  • Include an Idempotency-Key header with a unique string value on POST /v1/media requests.
  • If the header is omitted, Soku auto-derives a key from your user ID and a hash of the request payload.
  • If you send the same idempotency key with the same request body, the API returns the original cached response without uploading again.
  • If you send the same idempotency key with a different request body, the API returns a 409 error with code idempotency_conflict.

Error Responses

HTTP StatusError CodeDescription
400validation_errorThe url field is missing or not a valid URL
401unauthorizedMissing or invalid API key
403forbiddenSubscription is not active
409idempotency_conflictSame idempotency key used with a different request body
429rate_limit_exceededToo many requests. See Rate Limits.
500internal_errorFailed to download or store the media file
Example error response:
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_error",
    "message": "The 'url' field must be a valid HTTP or HTTPS URL.",
    "timestamp": "2026-02-28T12:00:00.000Z",
    "requestId": "req_abc123def456",
    "details": null
  }
}

Next Steps

TopicDescription
Posts APIUse uploaded media in post submissions
Templates APIGenerate OG images programmatically
Media Formats & LimitsPlatform-specific media requirements