npx claudepluginhub spotify/ads-agentic-toolsThis skill is limited to using the following tools:
Manage ad sets and ads via the Spotify Ads API. Read settings from `.claude/spotify-ads-api.local.md`.
Monitors deployed URLs for regressions after deploys, merges, or upgrades by checking HTTP status, console errors, network failures, performance (LCP/CLS/INP), content, and API health.
Share bugs, ideas, or general feedback.
Manage ad sets and ads via the Spotify Ads API. Read settings from .claude/spotify-ads-api.local.md.
.claude/spotify-ads-api.local.md for access_token, ad_account_id, auto_execute.https://api-partner.spotify.com/ads/v3/spotify-ads-api:configure first..claude-plugin/plugin.json to get the plugin version. Set SDK_HEADER="X-Spotify-Ads-Sdk: claude-code-plugin/$PLUGIN_VERSION" and include -H "$SDK_HEADER" on all API requests.The argument format is: <resource> <operation> [id]
ad-sets or adslist, create, get, updatead-sets listcurl -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"
Format as table: ID | Name | Campaign ID | Status | Format | Budget | Start
ad-sets createPrompt for required fields:
ADV_X_Y code, fetch from GET /ad_categories if needed)"age_ranges": [{"min": 18, "max": 34}]"genders": ["MALE", "FEMALE", "NON_BINARY"]"platforms": ["ANDROID", "DESKTOP", "IOS"] (NOT "MOBILE" or "CONNECTED_DEVICE")"placements": ["MUSIC"]MAX_BID, COST_PER_RESULT, or UNSET. Default to MAX_BID.15000000Important: Convert dollar amounts to micro-amounts by multiplying by 1,000,000. This applies to both budget.micro_amount and bid_micro_amount.
Structure: geo_targets is a flat object (NOT an array) with a required country_code and optional refinement arrays.
Lookup Geo IDs: Use the /targets/geos endpoint to find geo IDs:
# Search by location name
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
-H "$SDK_HEADER" \
"$BASE_URL/targets/geos?country_code=US&q=Connecticut&limit=20"
# Search by postal code
curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
-H "$SDK_HEADER" \
"$BASE_URL/targets/geos?country_code=US&q=06103&limit=20"
Response includes id, type, name, and parent_geo_name for each geo.
Geo Types:
REGION — States/provinces (e.g., Connecticut, California, Ontario)DMA_REGION — Designated Market Areas for media targeting (e.g., "Hartford & New Haven, CT")CITY — Cities and townsPOSTAL_CODE — ZIP codes (format: "US:06103", "CA:M5H")Targeting Examples:
"geo_targets": {
"country_code": "US"
}
"geo_targets": {
"country_code": "US",
"region_ids": ["4831725"] // Connecticut
}
"geo_targets": {
"country_code": "US",
"dma_ids": ["533"] // Hartford & New Haven, CT
}
"geo_targets": {
"country_code": "US",
"city_ids": ["4845411", "5284283"] // West Hartford, Colchester
}
"geo_targets": {
"country_code": "US",
"postal_code_ids": ["US:06103", "US:06105"]
}
"geo_targets": {
"country_code": "US",
"region_ids": ["4831725"], // Connecticut
"dma_ids": ["533"], // Hartford & New Haven DMA
"city_ids": ["4845411"] // West Hartford
}
Workflow:
/targets/geos with user's querygeo_targets object with appropriate IDsPre-flight audience estimate: Before executing the POST, run an audience estimate to validate targeting:
curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST -H "Authorization: Bearer $TOKEN" \
-H "$SDK_HEADER" \
-H "Content-Type: application/json" \
-d '{
"ad_account_id": "<AD_ACCOUNT_ID>",
"start_date": "<start_time>",
"asset_format": "<AUDIO|VIDEO|IMAGE>",
"objective": "<campaign_objective>",
"bid_strategy": "<MAX_BID|COST_PER_RESULT|UNSET>",
"bid_micro_amount": <bid>,
"budget": {"micro_amount": <budget>, "type": "<DAILY|LIFETIME>", "currency": "USD"},
"targets": { <same targets as above> }
}' \
"https://api-partner.spotify.com/ads/v3/estimates/audience"
Note: This endpoint is NOT scoped under /ad_accounts/{id}/ — it's at the top level: POST /estimates/audience. Use the base URL directly followed by /estimates/audience.
Display the estimate summary:
Audience Estimate:
Projected unique users: ~142,000
Estimated daily reach: 8,500 – 12,000
Estimated daily impressions: 15,000 – 22,000
Estimated CPM: $12.50 – $18.00
If the audience is too small (low projected users or 400 error), warn the user and suggest:
Ask whether to proceed, adjust targeting, or cancel before creating the ad set.
Create the ad set:
curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST -H "Authorization: Bearer $TOKEN" \
-H "$SDK_HEADER" \
-H "Content-Type: application/json" \
-d '{...}' \
"$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets"
ad-sets get <id>curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
-H "$SDK_HEADER" \
"$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ad_sets/$AD_SET_ID"
ad-sets update <id>Prompt for fields to update (min 1). Same fields as create, all optional.
ads listcurl -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"
Format as table: ID | Name | Ad Set ID | Status | Delivery
ads createPrompt for required fields:
GET /assets and prompt user to select:
asset_id (required — audio/video/image creative matching ad set format)logo_asset_id (required — logo image)companion_asset_id (required for AUDIO format — companion image)key (NOT type) and clickthrough_url (NOT url):
key: SHOP_NOW, LEARN_MORE, LISTEN_NOW, SIGN_UP, WATCH_NOW, BUY_NOW, DOWNLOAD, etc.clickthrough_url: landing page URLcurl -s -w "\nHTTP_STATUS:%{http_code}" -X POST -H "Authorization: Bearer $TOKEN" \
-H "$SDK_HEADER" \
-H "Content-Type: application/json" \
-d '{...}' \
"$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ads"
ads get <id>curl -s -w "\nHTTP_STATUS:%{http_code}" -H "Authorization: Bearer $TOKEN" \
-H "$SDK_HEADER" \
"$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/ads/$AD_ID"
ads update <id>Updateable fields: call_to_action, delivery, status.
auto_execute is true, execute directly.auto_execute is false, present the curl command and ask for confirmation.HTTP_STATUS: line from curl output to determine success or failure before interpreting the response body.