Claude
Skills
Sign in
Back

bulk

Included with Lifetime
$97 forever

Apply batch operations to multiple Spotify Ads API entities — pause or resume ad sets, update budgets, toggle ad delivery, swap creatives, or archive campaigns, ad sets, and ads.

Ads & Marketing

What this skill does


# Spotify Ads API — Bulk Operations

Apply batch changes to multiple entities in a single workflow. All operations follow the same pattern: list entities, select targets, confirm changes, apply sequentially.

## Setup

1. Read `access_token`, `ad_account_id`, and `auto_execute` from the active platform settings file:
   - Codex: prefer `.codex/spotify-ads-api.local.md`, then fall back to `.claude/spotify-ads-api.local.md`.
   - Claude: prefer `.claude/spotify-ads-api.local.md`, then fall back to `.codex/spotify-ads-api.local.md`.
2. Base URL: `https://api-partner.spotify.com/ads/v3`
3. If neither settings file exists, instruct the user to run `/spotify-ads-api:configure` first.
4. Read the active platform manifest for the plugin `version`: `.codex-plugin/plugin.json` on Codex or `.claude-plugin/plugin.json` on Claude.
5. Set `SDK_PRODUCT` to `codex-plugin` on Codex or `claude-code-plugin` on Claude. Set `SDK_HEADER="X-Spotify-Ads-Sdk: $SDK_PRODUCT/$PLUGIN_VERSION"` and include `-H "$SDK_HEADER"` on all API requests.

## Parsing Arguments

Parse the user's argument to determine the operation:
- `pause` — Pause multiple active ad sets or campaigns
- `resume` — Resume paused ad sets or campaigns
- `budget` — Update budgets across selected ad sets
- `delivery` — Toggle ad delivery ON/OFF
- `archive` — Archive multiple entities
- `creative` — Swap creative assets across ads
- If no argument, ask the user which operation.

All operations optionally accept a campaign filter: `pause --campaign <campaign_id>` narrows the entity list to a specific campaign.

---

## Selection Pattern

All operations follow this pattern:

### 1. List candidates

Fetch entities matching the operation's criteria. Present as a numbered table:

```
Active Ad Sets (5 found):
| # | ID | Name | Campaign | Budget | Format |
|---|----|------|----------|--------|--------|
| 1 | abc... | US 18-34 Audio | Summer Promo | $75/day | AUDIO |
| 2 | def... | US 25-54 Video | Summer Promo | $50/day | VIDEO |
| 3 | ghi... | UK All Audio | Q2 Brand | $100/day | AUDIO |
| 4 | jkl... | CA 18-44 Audio | Q2 Brand | $60/day | AUDIO |
| 5 | mno... | US All Display | Podcast Launch | $40/day | IMAGE |
```

### 2. Select targets

Ask the user to select entities. Support these selection formats:
- Individual numbers: `1, 3, 5`
- Ranges: `1-3`
- All: `all`
- Mixed: `1-3, 5`

### 3. Confirm changes

Show a summary of what will change. For budget operations, show before/after values. For status changes, show entity names and the target state.

### 4. Apply sequentially

Execute PATCH requests one at a time. Report success or failure for each entity. Continue on partial failure — do not stop the batch if one entity fails.

### 5. Show results

Display a final summary table:

```
Bulk Pause Results:
| Ad Set | Status | Result |
|--------|--------|--------|
| US 18-34 Audio | PAUSED | Success |
| UK All Audio | PAUSED | Success |
| US All Display | — | Failed: 403 Forbidden |

2/3 operations succeeded.
```

---

## Operations

### `pause`

Pause multiple active ad sets or campaigns.

#### List candidates

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets?statuses=ACTIVE&limit=50&sort_direction=DESC"
```

To filter by campaign: add `&campaign_ids=$CAMPAIGN_ID`.

To pause campaigns instead of ad sets, ask the user first, then:

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/campaigns?statuses=ACTIVE&limit=50&sort_direction=DESC"
```

#### Apply

For each selected ad set:

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -X PATCH -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "Content-Type: application/json" \
  -d '{"status":"PAUSED"}' \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets/$AD_SET_ID"
```

For campaigns, use the campaigns endpoint instead.

Skip entities that are already PAUSED — note them as "Already paused, skipped" in the results.

---

### `resume`

Resume paused ad sets or campaigns.

#### List candidates

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets?statuses=PAUSED&limit=50&sort_direction=DESC"
```

#### Apply

For each selected ad set:

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -X PATCH -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "Content-Type: application/json" \
  -d '{"status":"ACTIVE"}' \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets/$AD_SET_ID"
```

---

### `budget`

Update budgets across multiple ad sets.

#### List candidates

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets?limit=50&sort_direction=DESC"
```

Present the table with current budget amounts (convert `micro_amount` ÷ 1,000,000 to dollars) and budget type (DAILY/LIFETIME).

#### Ask for budget change

After selection, ask how to change the budget:
- **Set to**: "Set all selected ad sets to $X/day" or "$X lifetime"
- **Increase by %**: "Increase by 20%" — multiply each ad set's current budget by 1.2
- **Increase by $**: "Increase by $25" — add $25 (25,000,000 micro) to each
- **Decrease by %**: "Decrease by 15%"
- **Decrease by $**: "Decrease by $10"

#### Show before/after

```
Budget changes (+20%):
| Ad Set | Budget Type | Current | New |
|--------|-------------|---------|-----|
| US 18-34 Audio | DAILY | $75.00 | $90.00 |
| UK All Audio | DAILY | $100.00 | $120.00 |

Proceed with these changes?
```

#### Apply

For each selected ad set:

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -X PATCH -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "Content-Type: application/json" \
  -d '{"budget":{"micro_amount":<NEW_MICRO_AMOUNT>,"type":"<DAILY|LIFETIME>"}}' \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets/$AD_SET_ID"
```

Always convert dollar amounts to micro-amounts by multiplying by 1,000,000.

---

### `delivery`

Toggle ad delivery ON or OFF across multiple ads.

#### List candidates

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ads?limit=50&sort_direction=DESC"
```

To filter by campaign or ad set: add `&campaign_ids=$CAMPAIGN_ID` or `&ad_set_ids=$AD_SET_ID`.

Present the table showing current delivery status (ON/OFF), ad name, ad set name, and status.

#### Ask for target state

Ask the user: toggle all selected to ON, or toggle all to OFF?

#### Apply

For each selected ad:

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -X PATCH -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "Content-Type: application/json" \
  -d '{"delivery":"ON"}' \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ads/$AD_ID"
```

Skip ads already in the target delivery state.

---

### `archive`

Archive multiple entities. This is effectively permanent — there is no unarchive for campaigns, ad sets, or ads.

#### Ask entity type

Ask the user: "What do you want to archive — campaigns, ad sets, or ads?"

#### List candidates

Fetch non-archived entities of the selected type:

```bash
# For ad sets:
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets?statuses=ACTIVE&statuses=PAUSED&limit=50&sort_direction=DESC"
```

#### Confirm with warning

Before applying, warn: "Archiving is effectively permanent. Archived entities cannot be reactivated. Are you sure?"

#### Apply

For each selected entity:

```bash
curl -s -w "\nHTTP_STATUS:%{http_code}" -X PATCH -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "Content-Type: application/json" \
  -d '{"status":"ARCHIVED"}' \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets/$AD_SET_ID"
```

---

### `creative`

Swap creative assets across mul
Files: 1
Size: 12.2 KB
Complexity: 21/100
Category: Ads & Marketing

Related in Ads & Marketing