# Boost posts

Turn a published Facebook, Instagram, TikTok, LinkedIn, Pinterest, X or Reddit post into an ad that keeps its likes and comments.

Boosting runs a post you already published as an ad. The post keeps its likes, comments and shares, and Pozy builds the campaign, ad set and ad around it. One endpoint, `POST /v1/ads/boost`, works on every network that has organic posts. Google Ads and ChatGPT Ads have none, so they have no boost.

## Boost a post

Pass the post, the ad connection, the ad account, a goal and a budget.

```bash cURL
curl -X POST https://api.pozy.ai/v1/ads/boost \
  -H "Authorization: Bearer $POZY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: boost-65f1c0a9-launch" \
  -d '{
    "postId": "65f1c0a9e2b5af0012ab34cd",
    "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
    "adAccountId": "act_1234567890",
    "name": "Launch post boost",
    "goal": "traffic",
    "budget": { "amount": 25, "type": "daily" },
    "schedule": { "startDate": "2026-11-03T09:00:00Z", "endDate": "2026-11-10T09:00:00Z" },
    "targeting": { "countries": ["US", "CA"], "ageMin": 25, "ageMax": 45 },
    "linkUrl": "https://example.com/launch",
    "callToAction": "LEARN_MORE"
  }'
```
```ts Node
const res = await fetch("https://api.pozy.ai/v1/ads/boost", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.POZY_API_KEY}`,
    "Idempotency-Key": "boost-65f1c0a9-launch",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    postId: "65f1c0a9e2b5af0012ab34cd",
    accountId: "66b2e19d8c3f5a7e9d0b1c2d",
    adAccountId: "act_1234567890",
    name: "Launch post boost",
    goal: "traffic",
    budget: { amount: 25, type: "daily" },
    schedule: { startDate: "2026-11-03T09:00:00Z", endDate: "2026-11-10T09:00:00Z" },
    targeting: { countries: ["US", "CA"], ageMin: 25, ageMax: 45 },
    linkUrl: "https://example.com/launch",
    callToAction: "LEARN_MORE",
  }),
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
console.log(data.ad._id, data.ad.reviewStatus);
```
```python Python
import os, requests

resp = requests.post(
    "https://api.pozy.ai/v1/ads/boost",
    headers={
        "Authorization": f"Bearer {os.environ['POZY_API_KEY']}",
        "Idempotency-Key": "boost-65f1c0a9-launch",
    },
    json={
        "postId": "65f1c0a9e2b5af0012ab34cd",
        "accountId": "66b2e19d8c3f5a7e9d0b1c2d",
        "adAccountId": "act_1234567890",
        "name": "Launch post boost",
        "goal": "traffic",
        "budget": {"amount": 25, "type": "daily"},
        "schedule": {"startDate": "2026-11-03T09:00:00Z", "endDate": "2026-11-10T09:00:00Z"},
        "targeting": {"countries": ["US", "CA"], "ageMin": 25, "ageMax": 45},
        "linkUrl": "https://example.com/launch",
        "callToAction": "LEARN_MORE",
    },
    timeout=300,
)
resp.raise_for_status()
print(resp.json()["ad"]["_id"])
```

The response is the same `{ ad, message }` as a create, with `adType: "boost"`. On Meta, `ad.creative.effectiveObjectStoryId` points at the original post.

### Which post

| Field | Use it for |
| --- | --- |
| `postId` | A post published through Pozy. Pozy looks up the network's post id. |
| `platformPostId` | A post published outside Pozy, by its id on the network. On Reddit the `t3_` prefix is optional. On LinkedIn use the `share` or `ugcPost` id from "Copy link to post", not an `activity` id. |

### The body shape

A boost nests its settings, unlike the flat `POST /v1/ads/create` body. Do not mix the two.

| Field | Meaning |
| --- | --- |
| `budget` | `{ amount, type }`, `type` is `daily` or `lifetime`. Whole currency units. |
| `schedule` | `{ startDate, endDate }` as date-times. A lifetime budget needs `endDate`. |
| `targeting` | Countries, regions, cities, ZIPs, metros, custom locations, age, gender, languages and interests. Which ones apply depends on the network: see [Targeting](https://pozy.ai/docs/ads/targeting). |
| `linkUrl` + `callToAction` | A clickable destination on the boosted post. Send them together. |
| `status` | `PAUSED` creates everything paused so you can check it first. The default publishes at once. |
| `adSetId` | Put the boost under an ad set that already runs. That ad set then owns budget, schedule and targeting, so sending them returns `400`. |
| `bidStrategy`, `bidAmount`, `roasAverageFloor` | Optional bidding, same names as on create. LinkedIn bidding goes in `platformSpecificData`. |

## Goals by network

| Network | Goals a boost accepts | Notes |
| --- | --- | --- |
| Meta (Facebook, Instagram) | `engagement`, `traffic`, `awareness`, `video_views`, `lead_generation`, `conversions`, `app_promotion` | `lead_generation` needs `leadGenFormId`. |
| TikTok (Spark Ads) | Same as create | `targeting.countries` is required. |
| LinkedIn | `engagement`, `traffic`, `awareness`, `video_views`, `lead_generation`, `conversions` | `conversions` is boost-only on LinkedIn. |
| Pinterest | `engagement`, `traffic`, `awareness`, `video_views` | Minimum budget $5. |
| X | `engagement`, `traffic`, `awareness`, `video_views`, `app_promotion` | The boost carries the post's media, video included. It is the way to run video on X. |
| Reddit | Same as create | Only posts by a profile of the ad account. `video_views` needs a video post. |

## Network notes

### Meta

- `destinationType` picks where a click lands: `WEBSITE`, `MESSENGER`, `WHATSAPP`, `INSTAGRAM_DIRECT`, `INSTAGRAM_PROFILE` or `ON_AD`.
- To open a chat instead of a web page, use `goal: "engagement"` with `callToAction` set to `WHATSAPP_MESSAGE`, `MESSAGE_PAGE` or `INSTAGRAM_MESSAGE`, and leave `linkUrl` out. `whatsappPhoneNumber` picks a number paired with the Page. `workflowId` starts one of your [workflows](https://pozy.ai/docs/automations/workflows) in that chat.
- `VIEW_INSTAGRAM_PROFILE` is a boost-only button. Use the profile URL as `linkUrl`.
- `instagramAccountId` picks the Instagram identity the ad runs as. `GET /v1/ads/instagram-posts` lists Instagram posts you can boost.
- Boosting an Instagram video can take minutes while Meta re-hosts it. Do not retry on a client timeout.

### TikTok

A boost on TikTok is a Spark Ad. To promote another creator's video, send their Spark Code as `sparkAuthCode` with the video id in `platformPostId`. Several creators go in `sparkPosts[]`. Details on [TikTok Ads](https://pozy.ai/docs/ads/tiktok-ads#spark-ads).

### LinkedIn

Only Company Page posts can be boosted. A personal-profile post returns `422` with `INVALID_URN_TYPE`, and a Page post that is not approved for sponsorship returns `422` until the author approves it. To sponsor a Page post under a campaign whose bidding and targeting you control, use the thought leader format on create instead ([LinkedIn Ads](https://pozy.ai/docs/ads/linkedin-ads#creative-formats)).

### X and Reddit

On X, a boost can only change status, budget and bid afterwards. On Reddit, link the post's author to the ad account in Reddit Ads Manager first, or the boost returns `422` with `param: "platformPostId"`.

## Retries

Boosts are not idempotent on the networks' side. Send an `Idempotency-Key` header: the same key and body replays the original response, and distinct keys always create distinct ads. Without the header, Pozy still protects you from obvious duplicates:

- an identical request while the first is still running returns `409`
- an identical request within 10 minutes of a finished boost returns the ad already created

To boost the same post twice on purpose, use different keys.

## Errors

| Error | Cause | Fix |
| --- | --- | --- |
| `409` | An identical boost is still in progress | Wait, then read the ad from `GET /v1/ads`. |
| `422` `ads_connection_required` | The profile has no ad connection for that network | [Connect the ad account](https://pozy.ai/docs/ads#connect-an-ad-account). |
| `422` `linked_account_required` | An Instagram Login account was used on Meta | Use a `facebook` or `metaads` account in the same profile. |
| `400` on `callToAction` | A button without `linkUrl` | Send both, or use a messaging button on Meta. |
| `400` with `adSetId` | Budget, schedule or targeting sent alongside `adSetId` | Leave them out; the ad set owns them. |

## Endpoints

| Endpoint | What it does |
| --- | --- |
| [`POST /v1/ads/boost`](https://pozy.ai/docs/api/boostPost) | Boost post as ad |
| [`GET /v1/ads/instagram-posts`](https://pozy.ai/docs/api/listAdsInstagramPosts) | List Instagram posts to boost |
| [`GET /v1/ads/instagram-accounts`](https://pozy.ai/docs/api/listAdsInstagramAccounts) | List Instagram ad identities |
| [`GET /v1/ads/{adId}`](https://pozy.ai/docs/api/getAd) | Get ad details |
| [`GET /v1/ads/tree`](https://pozy.ai/docs/api/getAdTree) | Get campaign tree |
| [`PUT /v1/ads/{adId}/status`](https://pozy.ai/docs/api/updateAdStatus) | Pause or resume a single ad |
