---
title: "Upload an ad image from base64"
method: POST
path: "/v1/ads/images"
tags: ["Ad Creatives"]
---

# Upload an ad image from base64

`POST /v1/ads/images`

Uploads raw image bytes to the Meta ad account's image library, for callers whose
creatives aren't hosted at a public URL. Returns the image `hash` (Meta's identifier for
the asset) and the Meta-hosted `url`, which can be used directly as `imageUrl` on the
create endpoints. Max 30 MB decoded.

## Request body

- object
  - `accountId` string, required — Zernio SocialAccount id (posting or ads variant); its platform decides where the campaign is created.
  - `adAccountId` string, required — Platform ad account id (Meta act_<n>, Google customer id, LinkedIn account id, ...).
  - `imageBase64` string, required — Raw base64 image bytes, or a full data URL (the data:image/...;base64, prefix is stripped).
  - `filename` string — Optional filename shown in Meta's image library. Defaults to ad_image.jpg.

## Response `201`

Image uploaded

- object
  - `adAccountId` string
  - `image` object
    - `hash` string — Meta image hash, reusable wherever image_hash is accepted.
    - `url` string — Meta-hosted image URL; usable as imageUrl on the create endpoints.

## Other responses

- `400` — Invalid input, or Meta rejected the image
- `401` — Unauthorized
- `404` — The account or requested resource was not found or is not accessible. An account ID may have been disconnected and removed. Read GET /v1/accounts for current account IDs.
- `409` — The account exists but is inactive or needs reconnection. Reconnect it, then read GET /v1/accounts for its current account ID before retrying. Code: ads_connection_required.
- `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 image hash). Inspect `platformError.reason`.

## Changes

- **2026-09-16** `3e6ddf2a99ea` — 2 info
  - added the optional property `details/budgetScope` to the response with the `404` status
  - added the optional property `details/budgetScope` to the response with the `409` status
- **2026-09-15** `0dba7d004d75` — 4 info
  - added the optional property `details/quotaExhausted` to the response with the `404` status
  - added the optional property `details/quotaExhausted` to the response with the `409` status
  - added the optional property `details/quotaScope` to the response with the `404` status
  - added the optional property `details/quotaScope` to the response with the `409` status
- **2026-09-10** `e70ed06e7150` — 2 info
  - added the non-success response with the status `404`
  - added the non-success response with the status `409`
- **2026-08-21** `15e893e69e8c` — 1 info
  - added the non-success response with the status `502`

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/ads/images/post.md)

---

[API](https://skmtc.dev/zernio/apis/zernio-api.md) · [All operations](https://skmtc.dev/zernio/apis/zernio-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zernio/apis/zernio-api/revisions/dd3865482f9f?raw)
