Skip to main content
POST /v1/campaigns creates a campaign funded from your organization’s credit wallet. Requires the campaigns:write scope, and your organization must be enabled for wallet billing.
Campaign creation has a financial side effect: dailyBudget × durationDays is deducted from your wallet balance at creation. The Idempotency-Key header is required so retries never double-charge.

Prerequisites

  • An API key with the campaigns:write scope — see Authentication
  • Enough wallet balance to cover dailyBudget × durationDays (otherwise 402 insufficient_credit)
  • A Spotify track or playlist URL to promote

Typical flow

  1. Pick a strategyType from the catalog
  2. Create the campaign (wallet is debited)
  3. Poll campaign detail until status is active
  4. Track performance with metrics; adjust budget or stop via Managing campaigns

1. Pick a strategy

GET /v1/strategies (requires campaigns:read) returns the static catalog of strategyType values: Built-in strategies apply Soundlink’s default geographic tiering internally. Only custom accepts a tierTargeting object on create — sending tierTargeting with any other strategy returns 400 invalid_request.

2. Create the campaign

Expected (201):
The campaign starts in status creating and moves to active once setup completes (or failed if setup could not complete). Poll GET /v1/campaigns/{campaignId} to follow it.
TypeScript: soundlink.strategies.list() then soundlink.campaigns.create(body, { idempotencyKey }) — see TypeScript SDK.

Request fields

Supported genres

Alternative/Indie, Ambient/Sleep, Chill/Background, Classical, Country, Electronic/Dance, Hip-Hop/R&B, Latin/Reggaeton, Pop, Rock, Christmas Any other value returns 422 invalid_genre.

Creative direction

  • do_it_for_me (default when omitted) — Soundlink generates the ad creatives.
  • full_control — you supply your own videos. selectedCreatives must contain at least one videoId:
To get a videoId, upload videos in the Soundlink app or import them by URL with the Videos API — see Importing videos for the full flow (import, poll, limits).

Custom tier targeting

With strategyType: custom, tierTargeting is required. Provide at least one of:
  • customTierIds — non-empty list of tier definitions your organization already created in the app
  • customTiers — non-empty list of inline tiers: each needs name and percentBudget, plus optional countries (ISO codes eligible for ad targeting) and language (en, es, fr, de, or it)
Omitting tierTargeting, sending {}, or sending only empty arrays returns 400 invalid_request.
Allocation rules (violations return 422 invalid_tier_budget_allocation):
  • percentBudget values must sum to exactly 100
  • At most 5 active tiers (percentBudget > 0)
  • Each active tier must receive at least $1.50/day of dailyBudget (gross)

Idempotency

The Idempotency-Key header is required on POST /v1/campaigns (and on stop and budget endpoints — see Managing campaigns).
  • Any unique string up to 255 characters — a UUID or <action>-<date>-<ref> pattern works well
  • Keys are honored for 24 hours
  • Retrying with the same key and same body replays the recorded outcome — success or failure. A replayed success never creates a second campaign or a second charge.
  • Reusing a key with a different body returns 409 idempotency_key_conflict
  • If a concurrent request with the same key is still processing, you also get 409 — retry shortly
When a request times out or you never saw the response, retry with the same key — a new key could create a duplicate campaign and a duplicate wallet debit. When a request failed with a definitive error (for example 402 insufficient_credit) and you have fixed the cause, send the retry as a new request with a new key — failed outcomes may also be replayed for the original key.

Wallet funding and errors

The full cycle cost (dailyBudget × durationDays) is reserved from your wallet when the campaign is created. If the balance is too low the API returns 402:
Campaign creation does not automatically charge a saved payment method when the wallet balance is too low. Let the user top up the wallet in Soundlink by linking them to:
The user must be signed in. Soundlink resolves their organization from the current session (last-used org when they belong to more than one) and opens the wallet page. After the top-up, retry the request with a new Idempotency-Key (see Idempotency). If you already know the organization id and need a direct deep link, use /orgs/{organizationId}/settings/ledger instead. Common create errors: See Errors for the full list.

Next

Managing campaigns — budget changes, tiers, and stopping · Campaign metrics