spotify/ads-agentic-tools · Archived

assets

Upload, list, and manage Spotify Ads API creative assets — audio, video, and images for ad campaigns.

First seen Jun 24, 2026

Installation

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

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 6,941 B
  • docs SUMMARY.md 117 B

History

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

SKILL.md

Spotify Ads API — Asset Management

Upload, list, retrieve, and archive creative assets (audio, video, images) for use in ads.

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" assets "$@"; }

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

The argument format is: <operation> [arg]

  • upload <file_path> — Upload a new asset
  • list [audio|video|image] — List assets, optionally filtered by type
  • get <asset_id> — Get details of a specific asset
  • archive <asset_id> — Archive an asset
  • unarchive <asset_id> — Unarchive an asset
  • If no argument, ask which operation.

Operations

upload <file_path>

Two-step process following the API's required flow.

Step 1: Detect asset type from file extension

Extensions Asset Type
.mp3, .wav, .ogg AUDIO
.mp4, .mov VIDEO
.png, .jpg, .jpeg IMAGE

If the extension doesn't match any of these, ask the user to specify the asset type.

Step 2: Prompt for name

Use AskUserQuestion to ask for the asset name (2-120 characters). Default to the filename without extension.

Step 3: Create asset metadata

api POST "ad_accounts/{ad_account_id}/assets" \
  '{"asset_type":"AUDIO","name":"my-creative"}'

Extract id from the response.

Step 4: Upload the file

File uploads use raw curl (not the api wrapper) because they use multipart form data. Run eval $(api --env) before upload calls: it sets TOKEN, ADACCOUNTID, BASEURL, SDKHEADER, and SKILLHEADER (already scoped to this skill). Keep -H "$SDKHEADER" and -H "$SKILL_HEADER" on every upload call so the request stays attributable in reporting.

First, check the file size:

stat -f%z "/path/to/file"  # macOS
# or: stat --printf="%s" "/path/to/file"  # Linux

If file is <= 20MB — Simple upload:

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "$SKILL_HEADER" \
  -F "media=@/path/to/file" \
  -F "asset_type=AUDIO" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/assets/$ASSET_ID/upload"

If file is > 20MB — Chunked upload:

  1. Start the chunked upload session:
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "$SKILL_HEADER" \
  -H "Content-Type: application/json" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/assets/$ASSET_ID/chunked_upload/start"

Extract uploadsessionid and maxchunksize_mb from the response.

  1. Split the file into chunks:
split -b ${MAX_CHUNK_SIZE_MB}m /path/to/file /tmp/chunk_
  1. Upload each chunk (numbered starting from 1):
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "$SKILL_HEADER" \
  -F "media=@/tmp/chunk_aa" \
  -F "upload_section=1" \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/assets/$ASSET_ID/chunked_upload/transfer"
  1. Complete the chunked upload:
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "$SDK_HEADER" \
  -H "$SKILL_HEADER" \
  -H "Content-Type: application/json" \
  -d '{"upload_session_id":"<session_id>","number_of_sections":<total_chunks>}' \
  "$BASE_URL/ad_accounts/$AD_ACCOUNT_ID/assets/$ASSET_ID/chunked_upload/complete"
  1. Clean up temp chunks:
rm /tmp/chunk_*

Step 5: Poll for processing status

After upload, poll GET /assets/{id} until status changes from PROCESSING to READY or REJECTED. Poll every 3 seconds, max 60 seconds.

api GET "ad_accounts/{ad_account_id}/assets/$ASSET_ID"

Check the status field in the response. If still PROCESSING, wait 3 seconds and retry.

Step 6: Display result

Show the final asset details:

  • Asset ID — the UUID
  • Name — the asset name
  • Type — AUDIO, VIDEO, or IMAGE
  • Status — READY, PROCESSING, or REJECTED
  • URL — if available (when status is READY)
  • Duration — for audio/video assets
  • Dimensions — for image/video assets
  • Aspect ratio — for video/image assets

If the asset was REJECTED, explain that the file may not meet format requirements and suggest checking the supported formats section below.


list [audio|video|image]

List assets in the account, optionally filtered by type.

api GET "ad_accounts/{ad_account_id}/assets?asset_types=AUDIO&limit=50&sort_direction=DESC"

If no type filter is provided, omit the asset_types parameter to list all assets.

Format as table:

ID Name Type Status Duration/Dimensions Created
  • For audio assets: show duration
  • For video assets: show duration and dimensions
  • For image assets: show dimensions
  • Filter out archived assets unless the user specifically asks for them

If continuation_token is present in the response, note that more assets exist.


get <asset_id>

Get full details of a specific asset.

api GET "ad_accounts/{ad_account_id}/assets/$ASSET_ID"

Display all fields in readable format:

  • For audio: show name, type, status, duration, URL
  • For video: show name, type, status, duration, aspect ratio, dimensions, has_audio, URL
  • For image: show name, type, status, dimensions, aspect ratio, URL

archive <assetid> / unarchive <assetid>

Archive or unarchive an asset using the bulk action endpoint.

api PATCH "ad_accounts/{ad_account_id}/assets" \
  '{"action":"ARCHIVE","ids":["<asset_id>"]}'

For unarchive, use "action":"UNARCHIVE".

Confirm the action completed by displaying the updated asset status.


Supported Formats

Type Formats Recommendations
Audio MP3, WAV, OGG 128kbps+, 44.1kHz+ sample rate
Video MP4, MOV Aspect ratios: 16:9, 1.91:1, 1:1, 9:16
Image PNG, JPEG —
  • Max file size (simple upload): 20MB
  • Asset naming: 2-120 characters

Execution Behavior

  • If auto_execute is true, execute each API call directly.
  • If auto_execute is false, present the curl command and ask for confirmation before executing.
  • Display responses in readable format.
  • On error, show the error message from the response body.