Overlay user audio onto a video

Use this workflow when your customer has one video file and one audio file, and your product needs to publish a normal video with that audio already combined.

Important platform limitation: this guide does not attach arbitrary audio to an image post or carousel. TikTok and Instagram API publishing do not expose the same manual editor flow where a user picks multiple photos and adds a song. UniPost first creates a processed video, then the publish API receives that video as regular media.
SDK prerequisite: use UniPost SDK version 0.5.0 or later for this workflow. Starting in 0.5.0, the official SDKs no longer force callers to provide sizeBytes or size_bytes when reserving media uploads. Older SDK versions may still make your app calculate file size before calling POST/v1/media.

When to use this guide

Use this guide when a user uploads a video plus a separate voiceover, music bed, narration, or other audio track. UniPost stores both inputs with POST/v1/media, creates an async processing job with POST/v1/media/audio-overlays, then publishes the returned output_media_id with POST/v1/posts.

The resulting asset is a normal video. That keeps the final publish flow predictable across platforms and avoids asking the user to understand platform-specific music-library restrictions.

User-facing stepWhat your app should showUniPost API work
Pick video and audioShow two file slots: the base video and the audio to add. Make ownership or licensing expectations explicit before upload.No API call yet.
Upload the videoKeep the UI in an upload state until the video is usable. File size is optional: provide it when your app already knows the byte length, or omit it when your app does not know it yet.Reserve with POST/v1/media, upload bytes to the returned upload_url, then poll GET/v1/media/:media_id until the media is uploaded. The returned upload_url is not another UniPost JSON endpoint; it is the presigned file upload destination.
Upload the audioTreat audio as an input file, not a publishable asset. Label it as the audio track for the generated video.Use the same POST/v1/media upload flow with an audio MIME type such as audio/mpeg or audio/wav, then poll GET/v1/media/:media_id until the audio media is uploaded.
Choose audio behaviorOffer plain-language controls: keep original sound under the new audio, or replace the original sound entirely.Send mode: "mix" or mode: "replace" to POST/v1/media/audio-overlays.
Generate processed videoShow a processing state with a retry-safe action. The user should not have to repeat uploads if processing is still running.Poll the audio overlay job with GET /v1/media/audio-overlays/{id} until status is succeeded or failed.
Publish outputUse the generated video in the normal composer and make it clear this is the final video being posted.Publish output_media_id through POST/v1/posts as a regular video media_id.

Audio controls to expose

User intentAPI settingsUX copy
Add music or narration while keeping some original video soundmode: "mix", lower video_volume, keep audio_volume near full volume.Keep original sound
Replace the video's existing audio completelymode: "replace". video_volume is ignored for the final output.Replace original sound
Use only the beginning of a longer audio filefit: "trim_to_video"Stop audio at the end of the video
Repeat a short audio file until the video endsfit: "loop_to_video"Loop audio to match video length

API steps

Step 1: Upload the video input

Reserve a video upload with POST/v1/media. File size is optional: provide it when your app already knows the byte length, or omit it when your app does not know it yet. UniPost hydrates size_bytes after the upload lands.

Upload the raw video bytes to the returned upload_url, then poll GET/v1/media/:media_id until the video is uploaded. The returned upload_url is not another UniPost JSON endpoint; it is the presigned destination for the actual file bytes.

Step 2: Upload the audio input

Reserve and upload the audio file with the same media upload flow and an audio MIME type such as audio/mpeg or audio/wav. Keep the returned audio media_id for processing only; do not publish the raw audio media as the post asset.

Step 3: Generate the overlay video

Create the audio overlay job with POST/v1/media/audio-overlays. Use mode: "mix" to keep some original video sound, or mode: "replace" to remove the original sound. Use an Idempotency-Key tied to the user's generate action so browser retries do not create duplicate jobs.

Poll GET /v1/media/audio-overlays/{id}. When status is succeeded, read output_media_id. That media ID points to the processed video that already contains the requested audio.

Step 4: Publish the processed video

Publish the final video by passing output_media_id in media_ids on POST/v1/posts. From the publish API's perspective, this is a regular video media asset.

Example workflow

Failure handling

Keep uploaded input media IDs so the user can retry processing without uploading the same files again. If the overlay job returns status: "failed", show the job error message, keep the selected audio settings visible, and let the user retry with the same video_media_id and audio_media_id.

If publishing fails after processing succeeds, do not rerun the overlay job. Reuse the same output_media_idand retry the publish flow according to the post error contract.

Reference