---
title: "Duplicate an ad"
method: POST
path: "/v1/ads/{adId}/duplicate"
tags: ["Ad Campaigns"]
---

# Duplicate an ad

`POST /v1/ads/{adId}/duplicate`

Duplicates a single ad via Meta's native `POST /{ad-id}/copies`. The copy is created
paused. `adSetId` retargets the copy into another ad set; omitted = the source's own ad
set. Accepts the Zernio ad id or the platform ad id. Sync discovery is triggered
automatically (`syncAfter: false` to skip). Creative settings returned by Meta,
including explicit promotion metadata and creativeFeatures, are preserved when the
native copy requires a creative rebuild. Metadata Meta does not return cannot be recovered.
When Meta refuses the native copy with its capability error (code 3), which happens for
some creatives built by other tools, the ad is rebuilt instead: a new creative from the
source's returned spec and a new ad in the target ad set, carrying the source name,
status option, rename options and tracking specs.

## Path parameters

- `adId` string, required

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `adSetId` string — Destination platform ad set id (defaults to the source's ad set)
  - `statusOption` 'ACTIVE' | 'PAUSED' | 'INHERITED_FROM_SOURCE'
  - `renameStrategy` 'DEEP_RENAME' | 'ONLY_TOP_LEVEL_RENAME' | 'NO_RENAME'
  - `renamePrefix` string
  - `renameSuffix` string
  - `syncAfter` boolean
  - `reuseSourceCreative` boolean — Point the copy at the source ad's creative object instead of copying it, so the copy keeps the same Facebook post, the same Instagram media, their existing likes, comments and shares, and the full creative setup (text variations included). This is what Ads Manager's "show existing reactions, comments and shares" does. Meta's native copy always publishes new posts. A creative belongs to one ad account, so `adSetId` must be in the source ad's account. 400 when the source ad has no creative yet.

## Response `200`

Ad duplicated

- object
  - `copiedAdId` string — Platform ID of the new ad
  - `discovery` 'triggered' | 'skipped' | 'failed'
  - `raw` object

## Other responses

- `400` — Invalid input
- `401` — Unauthorized
- `403` — Returned with code `ads_allowance_exceeded` when the team has no payment method on file and has reached the 500 free live ads: add a card to resume.
- `404` — Ad not found
- `501` — Only supported on Meta (facebook/instagram)

## Changes

- **2026-09-22** `106013ac73b8` — 1 info
  - added the new optional request property `reuseSourceCreative`
- **2026-09-02** `017dff7e4324` — 1 info
  - added the non-success response with the status `403`

[Change history](https://skmtc.dev/zernio/apis/zernio-api/changes/v1/ads/:adId/duplicate/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/106013ac73b8?raw)
