spotify/ads-agentic-tools · Archived

export

Export Spotify Ads API campaign data to CSV — full campaign hierarchies with ad sets, ads, targeting, budgets, and performance metrics for offline review, campaign analysis, or budget reconciliation.

First seen Jun 23, 2026

Installation

$ npx skills add spotify/ads-agentic-tools --skill export

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from spotify/ads-agentic-tools.

npx skills add spotify/ads-agentic-tools

Browse all from spotify/ads-agentic-tools

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 11
License LICENSE
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Bash, AskUserQuestion

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,800 B
  • docs SUMMARY.md 215 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

Spotify Ads API — Campaign Data Export

Export campaign hierarchies to CSV for offline review, combining entity data with optional performance metrics.

Setup

Set the plugin root and define the request wrapper:

PLUGIN_ROOT="${CODEX_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-.}}"
api() { "$PLUGIN_ROOT/scripts/api-request.sh" export "$@"; }

Before the first Ads API v3 call, read and follow $PLUGIN_ROOT/skills/api-reference/references/live-openapi.md.

To retrieve settings values (TOKEN, ADACCOUNTID, AUTOEXECUTE, BASEURL, SDKHEADER, SKILLHEADER, PLUGIN_VERSION) for use outside API calls, run api --env. The output is eval-safe, so eval $(api --env) assigns them all.

Parsing Arguments

  • No argument → Export all campaigns
  • <campaign_id> (UUID) → Export a specific campaign
  • --metrics → Include performance metrics (impressions, spend, reach, etc.)
  • --date-range <start> <end> → Metric date range (ISO 8601). Default: last 30 days.
  • If ambiguous, ask the user.

Step 1: Ask Export Preferences

Ask the user to confirm:

  • Scope: All campaigns or a specific campaign?
  • Include metrics? Entity data only, or include performance metrics?
  • Output path: Default ./spotify-ads-export-YYYY-MM-DD.csv, or user-specified path.

Step 2: Fetch Entity Data

Fetch all entity data with full pagination. Unlike other skills that show the first page, export must retrieve every entity to produce a complete file.

Fetch campaigns

api GET "ad_accounts/{ad_account_id}/campaigns?limit=50&offset=0"

Check paging.totalresults in the response. If totalresults > 50, make additional requests incrementing offset by 50 until all campaigns are fetched. For a single-campaign export, use:

api GET "ad_accounts/{ad_account_id}/campaigns/$CAMPAIGN_ID"

Fetch ad sets

api GET "ad_accounts/{ad_account_id}/ad_sets?limit=50&offset=0"

For a single campaign: add &campaignids=$CAMPAIGNID. Paginate with offset until all ad sets are fetched.

Fetch ads

api GET "ad_accounts/{ad_account_id}/ads?limit=50&offset=0"

For a single campaign: add &campaignids=$CAMPAIGNID. Paginate with offset until all ads are fetched.


Step 3: Fetch Metrics (if requested)

When metrics are included, fetch aggregate reports at each entity level. For a single-campaign export, add entityids=$CAMPAIGNID&entityidstype=CAMPAIGN to every report request so the export does not rely on the first unfiltered page containing the requested campaign's metrics.

Campaign-level metrics

api GET "ad_accounts/{ad_account_id}/aggregate_reports?\
entity_type=CAMPAIGN&\
fields=IMPRESSIONS&fields=SPEND&fields=CLICKS&fields=REACH&fields=FREQUENCY&fields=CTR&fields=COMPLETES&\
granularity=LIFETIME&\
entity_status_type=CAMPAIGN&\
limit=50"

If a date range is specified, switch to granularity=DAY and add &reportstart=<start>&reportend=<end>. Use UTC midnight timestamps such as 2026-05-01T00:00:00Z. Do not send reportstart or reportend with granularity=LIFETIME. Paginate with continuation_token if present in the response.

Ad set-level metrics

api GET "ad_accounts/{ad_account_id}/aggregate_reports?\
entity_type=AD_SET&\
fields=IMPRESSIONS&fields=SPEND&fields=CLICKS&fields=REACH&fields=FREQUENCY&fields=COMPLETES&fields=COMPLETION_RATE&\
granularity=LIFETIME&\
entity_status_type=AD_SET&\
include_parent_entity=true&\
limit=50"

For a single-campaign export, add &entityids=$CAMPAIGNID&entityidstype=CAMPAIGN. Paginate with continuation_token if present in the response.

Ad-level metrics

api GET "ad_accounts/{ad_account_id}/aggregate_reports?\
entity_type=AD&\
fields=IMPRESSIONS&fields=SPEND&fields=CLICKS&fields=REACH&\
granularity=LIFETIME&\
entity_status_type=AD&\
include_parent_entity=true&\
limit=50"

For a single-campaign export, add &entityids=$CAMPAIGNID&entityidstype=CAMPAIGN. Paginate with continuation_token if present.


Step 4: Build and Write CSV

CSV columns

The CSV is denormalized — one row per ad, with campaign and ad set data repeated on each row. Ad sets with no ads get a row with blank ad columns.

Entity columns:

  • campaignid, campaignname, campaignstatus, campaignobjective
  • adsetid, adsetname, adsetstatus, adsetformat, adsetbudgettype, adsetbudgetamount, adsetbidstrategy, adsetbidamount, adsetstarttime, adsetendtime, adsetdelivery
  • adsetgeocountry, adsetgeoregions, adsetagemin, adsetagemax, adsetplatforms, adsetplacements, adsetgenders
  • adid, adname, adstatus, addelivery, adtagline, adadvertisername, adctakey, adcta_url

Metric columns (when --metrics is used):

  • impressions, spend, clicks, reach, frequency, ctr, completes, completion_rate

Data transformations

  • Budget/bid amounts: Divide micro_amount by 1,000,000 to display in the billing currency (e.g., 50000000 → 50.00).
  • Metric SPEND: Values from aggregate_reports are already in the billing currency — display directly.
  • Geo targeting: Flatten to adsetgeocountry = country code string, adsetgeoregions = comma-separated region/DMA/city names if available (IDs if names are not in the response). Note: DMA-level targeting (dma_ids) is no longer available for new ad sets, but older campaigns may still contain DMA data in their geo targets.
  • Age ranges: Extract first range's min and max into adsetagemin and adsetagemax.
  • Arrays (platforms, placements, genders): Join with commas (e.g., "ANDROID,DESKTOP,IOS").
  • CSV quoting: Wrap values containing commas, quotes, or newlines in double quotes. Escape internal double quotes by doubling them ("").

Join logic

Match entities by ID:

  • Each ad belongs to an ad set (via adsetid) which belongs to a campaign (via campaign_id).
  • Metrics join on entity_id from the report rows to the entity's id.
  • If an entity has no metrics (zero impressions, new campaign), include the row with blank metric columns.

Write the file

Write the CSV header and rows with a structured CSV writer. Prefer Python's standard csv module, or use jq @csv if all rows are already available as JSON. Do not build CSV rows with echo or string concatenation; that will corrupt values containing commas, quotes, or newlines.

Example Python shape:

import csv

columns = [
    "campaign_id", "campaign_name", "campaign_status", "campaign_objective",
    "ad_set_id", "ad_set_name", "ad_set_status", "ad_set_format",
    "ad_set_budget_type", "ad_set_budget_amount", "ad_set_start_time",
    "ad_set_end_time", "ad_id", "ad_name", "ad_status", "ad_delivery",
    "impressions", "spend", "clicks", "reach",
]

with open(output_path, "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=columns, extrasaction="ignore")
    writer.writeheader()
    writer.writerows(rows)

Build rows from parsed API JSON before writing. Let the CSV writer handle quoting and escaping.


Step 5: Display Summary

After writing the file, display:

Export complete: ./spotify-ads-export-2026-05-14.csv
  Campaigns: 3
  Ad Sets: 7
  Ads: 12
  Metrics included: Yes (lifetime, last 30 days)
  File size: 4.2 KB

Execution Behavior

  • If auto_execute is true, execute all API calls directly and write the file.
  • If auto_execute is false, present the curl commands for the first fetch and ask for confirmation before executing. After confirmation, execute all remaining fetches without additional prompts.
  • Always check the HTTP_STATUS: line from curl output to determine success or failure before interpreting the response body.
  • On error from any fetch, show the error and continue with available data. Note which entity types are missing from the export.
  • For large accounts (50+ campaigns), note that pagination will require multiple API calls and may take 30-60 seconds.

Cross-references

  • For server-generated async CSV reports with different column structure, use /spotify-ads-api:report async-create.
  • For a quick visual overview instead of a file export, use /spotify-ads-api:dashboard.
  • After reviewing exported data, use /spotify-ads-api:bulk for batch changes.