---
title: "Upload an ad video"
method: POST
path: "/v1/ads/videos"
tags: ["Ad Creatives"]
---

# Upload an ad video

`POST /v1/ads/videos`

Standalone ad-video upload (parallel to POST /v1/ads/images), so a video creative can
be rendered via POST /v1/ads/preview or attached via `video.id` on POST /v1/ads/create
before an ad exists.

Accepts either an https `videoUrl` we download server-side (SSRF-guarded) or raw
`videoBase64` bytes; exactly one is required. `videoBase64` is capped by Vercel's body
limit — around 4.5 MB payload in practice, so larger videos must come via `videoUrl`.

Returns the Meta `video.id` (reusable wherever `video.id` is accepted) plus Meta's
auto-generated poster URL when available. The endpoint waits until Meta reports the
video ready (chunked upload + transcode can take minutes; the handler runs up to
800 s).

## Request body

- object
  - `accountId` string, required — Zernio SocialAccount id (posting or ads variant) used to resolve the Meta token.
  - `adAccountId` string, required — Meta ad account id (act_<n>).
  - `videoUrl` string — Public https URL of the video; downloaded server-side (SSRF-guarded) before chunked upload. Provide exactly one of videoUrl or videoBase64.
  - `videoBase64` string — Raw base64 video bytes, or a full data URL (the data:video/...;base64, prefix is stripped). Capped by Vercel's body limit (~4.5 MB payload). Provide exactly one of videoUrl or videoBase64.
  - `filename` string — Optional filename shown alongside the upload session. Applied only when uploading via videoBase64.

## Response `201`

Video uploaded and ready

- object
  - `adAccountId` string
  - `video` object
    - `id` string — Meta video id, reusable as video.id on POST /v1/ads/create and inside POST /v1/ads/preview creativeSpec.
    - `thumbnailUrl` string, nullable — Meta-hosted poster URL if available; null when Meta has not produced a poster yet.

## Other responses

- `400` — Invalid input, or Meta rejected the upload
- `401` — Unauthorized
- `501` — Only supported on Meta (facebook/instagram)
- `502` — Meta accepted the request then failed to produce the media (upload session, chunk transfer, processing timeout, or a response with no video id). Inspect `platformError.reason`.

---

[API](https://skmtc.net/zernio/apis/zernio-api.md) · [All operations](https://skmtc.net/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/zernio/zernio-api/revisions/ac5fffe58a63/schema)
