> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ads

> Manage boosted ads through the Ayrshare GraphQL API with one set of operations that takes the ads platform as an argument.

The ads operations take the ads platform as an argument, so the same operation works on every ads platform Ayrshare supports. Today that is `FACEBOOK` and `INSTAGRAM`.

Each operation calls the matching [REST ads endpoint](/docs/apis/ads/overview) and returns its response unchanged. Authentication and limits are the same as REST. A failed call returns a GraphQL error: `extensions.status` carries the REST status, and `extensions.code` the Ayrshare error code when the REST error has one. See [Errors](/docs/apis/graphql/errors). Ads operations need the Ads add-on. Without it, every call returns an error with `extensions.status` `403` and `extensions.code` `399`.

## Operations

| Operation | Type | REST endpoint |
| - | - | - |
| `adAccounts` | Query | `GET /ads/{platform}/accounts` |
| `adTargetingSearch` | Query | `GET /ads/{platform}/interests`, `/regions` or `/cities` |
| `ads` | Query | `GET /ads/{platform}/ads` |
| `adHistory` | Query | `GET /ads/{platform}/history` |
| `updateAd` | Mutation | `PUT /ads/{platform}/ads` |
| `boostPost` | Mutation | `POST /ads/{platform}/boost` |

Every operation also takes an optional `profileKey` to act on a User Profile. All of them return the REST response as JSON, so they take no field selection.

## List ad accounts

Start here. Use the `accountId` values in the response wherever an operation asks for `accountId`.

```graphql theme={"system"}
query {
  adAccounts(platform: FACEBOOK, limit: 10)
}
```

## Search targeting options

`kind` picks the search: `INTERESTS` for audience targeting, `REGIONS` or `CITIES` for locations. Each kind takes only its own arguments. For example, `countryCode` and `regionId` work only with `CITIES`, and `INTERESTS` needs `search`.

```graphql theme={"system"}
query {
  adTargetingSearch(platform: INSTAGRAM, kind: INTERESTS, search: "running")
}
```

```graphql theme={"system"}
query {
  adTargetingSearch(platform: FACEBOOK, kind: CITIES, search: "Austin", countryCode: "US")
}
```

## List ads

Pass at least one of `campaignId`, `accountId`, `adId`, `postId` or `socialPostId`. `socialPostId` is the network's own post id, for posts not published through Ayrshare.

```graphql theme={"system"}
query {
  ads(platform: FACEBOOK, accountId: "act_1234567890")
}
```

## See what an ad has cost

```graphql theme={"system"}
query {
  adHistory(platform: FACEBOOK, startDate: "2026-09-01", endDate: "2026-09-30")
}
```

## Pause or resume an ad

`updateAd` changes real ad spend. `PAUSED` stops spending, `ACTIVE` resumes it, and `DELETED` or `ARCHIVED` retires the ad. The same status is also set on the ad's ad set and campaign, so any other ads in that ad set or campaign change with it. A campaign or ad set the boost was attached to with `attachTo` keeps its own status, and the ad runs only while the campaign and ad set above it are active.

```graphql theme={"system"}
mutation {
  updateAd(platform: FACEBOOK, adId: "120210000000000000", status: PAUSED)
}
```

## Boost a post

`boostPost` spends real money from the ad account. It turns a published post into an ad.

* Pass `postId` (the Ayrshare post id) or `socialPostId` (the network's own post id).
* Get `accountId` from `adAccounts`.
* `budget.amount` is in the ad account's currency. Leave `budget` out only when `attachTo.adSetId` adds the ad to an ad set you already run, which keeps its own budget. Leave `targeting` out then too: the ad set keeps its own. See [Boost into an Existing Campaign or Ad Set](/docs/apis/ads/facebook/boost-post#attach-to).
* `schedule`, `targeting`, `callToAction`, `attachTo` and `status` are optional. If you leave out `status` and `schedule`, the ad is **active, starts now and has no end date**, so it keeps spending until you pause it. Set `status: PAUSED` or `schedule.end` to limit it.
* Put settings that only one platform has under `platformOptions`, keyed by platform. On Facebook and Instagram, `adName` and `bidAmount` are **required** there, for example `platformOptions: { facebook: { adName: "Autumn sale", bidAmount: 2 } }`. Without them the boost returns a missing-fields error. With `attachTo.adSetId`, leave `bidAmount` out: the ad set keeps its own bid.
* On Facebook and Instagram, Meta refuses the ad until the ad account has a payment method attached and, in the EU, EEA and Switzerland, personalized ads are turned on for the account linked to the Page. See [Boost Post](/docs/apis/ads/facebook/boost-post).

```graphql theme={"system"}
mutation {
  boostPost(
    platform: FACEBOOK
    accountId: "act_1234567890"
    postId: "RNlSOkyxl9G3EDhlPuCK"
    goal: "engagement"
    budget: { amount: 20, type: DAILY }
    schedule: { start: "2026-10-10T09:00:00Z", end: "2026-10-17T09:00:00Z" }
    targeting: { ageMin: 25, ageMax: 45, locations: { countries: ["US"] } }
    platformOptions: { facebook: { adName: "Autumn sale", bidAmount: 2 } }
    idempotencyKey: "4f9c2a7e-1b3d-4c8e-9a6f-2d5b7e0c1a34"
  )
}
```

Some arguments take more than one form, so they use the `JSON` type:

* `accountId` takes a string or a number.
* The `schedule` dates take an ISO 8601 date or date-time, such as `"2026-10-10T09:00:00Z"`. Use that form rather than a number. `schedule.end` also takes `0` for no end date.
* Location keys take one value or a list.
* `targeting.interests` takes ids as strings or numbers.
* `platformOptions` takes an object.

> [!TIP]
>
> Send a new `idempotencyKey`, such as a UUID, with each boost. If a call times out or fails, retry with the same key and the same arguments.
>
> * If the first boost finished, the retry returns its response instead of creating and paying for a second ad.
> * If the first boost is still in progress, the retry returns an error with `extensions.status` `409`. Wait, then retry with the same key. Do not switch to a new key.
> * Reusing a key with different arguments also returns `409`.

To stop the ad spending, call `updateAd` with `status: PAUSED`. `boostFacebookPost` and `instagramBoostPost` still work.

The per-platform operations, such as `facebookAdAccounts` and `instagramAds`, still work and are unchanged.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.