Skip to content

v1.9.0

Latest

Choose a tag to compare

@henry-jackson henry-jackson released this 01 Oct 20:25
· 26 commits to main since this release
6c5a0a1

Spotify Ads API Plugin v1.9.0

This release replaces secret-based OAuth with Authorization Code with PKCE, adds a media-plan-to-draft workflow, and makes the plugin work on Windows and Linux. API requests now follow the live public OpenAPI document instead of a bundled copy, create requests are protected against duplicate submissions on retry, and every Ads API call is attributed to the skill that made it.

Highlights

OAuth with PKCE

Setup now uses Authorization Code with PKCE (S256) and team-owned client IDs. No application secret is collected or stored.

  • Public-client authorization and refresh requests send client_id instead of an application secret
  • Cryptographic verifier and state generation, with exact loopback callback validation
  • A printed-URL fallback when a browser cannot be opened automatically
  • Automatic token refresh on every platform, without relying on the macOS Keychain or any other platform credential store
  • Setup documentation separates registering a team application from individual authorization, and explains client-level attribution and rate-limit isolation

Media plan to draft

A new media-plan-to-draft skill turns advertiser or third-party media plans into a reviewed Spotify Ads draft hierarchy:

  • Reads spreadsheets, CSVs, documents, presentations, PDFs, and plain text
  • Tracks where every value came from (cell, page, or table) and reconciles totals
  • Keeps Auction lines separate from reserved or non-Spotify lines
  • Enriches the plan with the live ad product catalog, targeting IDs, assets, and audience forecasts, including low and high bid scenarios
  • Labels each value as CONFIRMED, VALIDATED, INFERRED, PLACEHOLDER, DEFERRED, or BLOCKED
  • Shows an exact preview and creates drafts only after you approve that scope; it never publishes

Windows and Linux support

The plugin no longer depends on macOS-only commands. Python is detected as python3, python, or py, and asset upload paths use portable stat and temporary-directory handling.

Live API contract

Each workflow now fetches the current public Ads API v3 OpenAPI document once, checks every planned request's parameters and body against it, and stops before making any API call if the document cannot be retrieved. The bundled OpenAPI copy has been removed, so guidance can no longer drift behind the live API.

API and documentation updates

  • Added a Reserved buying flow that fetches the fixed Reserved rate before an audience forecast, uses it as the bid, and reports it separately from forecast CPM and bid suggestions
  • Refined ad product catalog validation for creates and updates, including the parent and runtime context a change depends on
  • Pixel discovery now uses GET /businesses/{id}/datasets and the pixel field on each dataset, replacing GET /businesses/{id}/pixels, which rejected every request
  • Added retry-safety guidance for create requests
  • Renamed the API reference skill to spotify-ads-api-reference to meet Agent Skills naming rules
  • Documented installing from the marketplace through the Claude and Codex apps
  • AGENTS.md is now the only project instruction file; Claude Code 2.1.277 and later read it directly

Security and reliability

  • Create requests sent through the request wrapper carry an automatic Idempotency-Key derived from the request contents, so a retried request is recognised by the server instead of creating a duplicate. Use --no-dedup-key to opt out
  • Raw curl calls that bypass the request wrapper are now refreshed and attributed by the PreToolUse hook, including upload flows written as $BASE_URL/.... When the skill can only be inferred from the session, the value carries an -inferred suffix
  • Fixed eval $(api --env) silently setting nothing, which caused asset and audience uploads to send an empty Authorization header
  • Initial OAuth tokens are written straight to a settings file that is private (mode 0600) from the moment it is created, and never appear in helper output
  • Direct tokens are entered at a hidden terminal prompt, keeping them out of chat and command arguments
  • Refresh tokens are passed to the refresh helper on stdin rather than as command arguments
  • The Codex hook resolves from the installed plugin directory instead of falling back to the workspace
  • Removed the obsolete root settings.json that caused Claude app marketplace sync to reject the plugin
  • Added regression tests for PKCE, token refresh, the request wrapper, OpenAPI fetching, marketplace metadata, and hook attribution

Upgrade notes

  • Run /configure once to reauthorize with PKCE. Existing access tokens keep working until they expire, but cannot be refreshed without reauthorizing.
  • Application secrets and macOS Keychain entries from earlier versions are no longer used and can be removed.
  • References to the old API reference skill name should use spotify-ads-api-reference.
  • The plugin version is synchronized as 1.9.0 across Claude Code, Codex, and Antigravity manifests.

Full changelog: v1.8.0...v1.9.0