Skip to main content
POST
Upload media files directly to Genviral’s storage, then finalize the stored bytes into a CDN-backed Media Library record. A preparation never creates a visible file by itself. One upload URL carries up to 100 MB (images up to 50 MB). For larger videos, up to 500 MB, use Start Multipart Upload.

How It Works

  1. Call this endpoint with the file’s content type and a stable Idempotency-Key
  2. Receive a file id and presigned uploadUrl
  3. Upload your file directly to the uploadUrl using a PUT request
  4. Call POST /api/partner/v1/files/{fileId}/finalize with the same media metadata and a stable Idempotency-Key
  5. Use the finalized file.url in post creation or pack-image attachment requests

Body Parameters

string
required
MIME type of the file. Supported types:
  • Images: image/jpeg, image/png, image/gif, image/webp, image/heic, image/heif
  • Videos: video/mp4, video/quicktime, video/x-msvideo, video/webm, video/x-m4v
string
Original filename for reference (optional). Used for display purposes only.
number
Optional video duration in seconds. Also accepts duration_seconds, duration, durationSec, or video_duration_sec. Stored with the CDN file record so /posts can hydrate validation metadata when you use the returned url.
number
Optional file size in bytes. Also accepts size. Images: 1 through 52,428,800 (50 MB). Videos: 1 through 104,857,600 (100 MB) on this endpoint; larger videos use Start Multipart Upload.

Response

Successful requests return 201 with:
  • uploadUrl - Presigned URL to upload your file (expires in 10 minutes)
  • id - Stable upload identity used by the finalize endpoint
  • contentType - The content type you specified
  • expiresIn - Seconds until the upload URL expires (600)
The finalize response contains file, including its verified byte size and public https://cdn.vireel.io/... URL. Invalid, absent, empty, oversized, or MIME-mismatched bytes are rejected without creating a Media Library row.

Using With Packs

If your goal is to add a local file to a pack:
  1. Call this endpoint and capture data.id + data.uploadUrl.
  2. Upload your bytes to data.uploadUrl with PUT.
  3. Finalize the upload and capture data.file.url.
  4. Call Add Pack Image with image_url = data.file.url.

Examples

Upload a video

Error Responses

  • 400 invalid_request - Idempotency-Key is missing or invalid
  • 400 invalid_json - Request body is not valid JSON
  • 422 invalid_payload - Invalid content type, missing required fields, or a declared size above the single-upload limit
  • 401 - authentication failed (missing/invalid/revoked token)
  • 402 subscription_required - active Creator/Professional/Business plan required
  • 403 tier_not_allowed - Scheduler tier cannot use Partner API
  • 500 create_failed - Failed to initialize upload (retry)
The presigned upload URL expires after 10 minutes. If it expires before you upload, simply request a new one.
POST /files only prepares an expiring upload destination. The file is ready for use only after the PUT succeeds and POST /files/{fileId}/finalize returns the canonical CDN-backed record.