GET /v1/campaigns. For paid campaigns, use Syncing campaigns.
For the monthly Self-Serve plan and listener cap, see Self-Serve.
Requires soundlinks:read. See Authentication. To create, archive, or send a test event, see Creating soundlinks.
Existing API keys keep the scopes they were minted with. Create a new key
and add
soundlinks:read to call these routes.soundlinkId on these routes returns 404. Missing soundlinks:read returns 403 insufficient_scope. See Errors for the full list.
List soundlinks
GET /v1/soundlinks
Includes archived rows (status: archived). Supports pagination:
sortBy is createdAt. soundlinkId is a URL-safe string — the same ID in the public sndl.ink URL — not a campaign UUID.
pagination.page >= pagination.totalPages.
Soundlink detail
GET /v1/soundlinks/{soundlinkId}
Returns catalog fields plus autoFollow, artistIdFollow, metaPixelId, tiktokPixelId, appleMusicUrl, and youtubeMusicUrl. appleMusicUrl and youtubeMusicUrl are the stored URLs, or null when unset. An Apple album share-sheet link is returned as the canonical song URL. List items do not include appleMusicUrl or youtubeMusicUrl. Archived soundlinks still appear (status: archived). Unknown, cross-org, or campaign-linked IDs return 404. The Meta CAPI token is never returned.
Use the soundlinkId from the list response in all /metrics/* paths.
Typical sync flow
- Daily:
GET /v1/soundlinks— upsert catalog - Daily: soundlink metrics per active soundlink
Organization scope
Your organization is determined only from the API key (or OAuth token). You never pass an organization id in query params.- Soundlink list and detail JSON uses
organizationId. - Metrics JSONL / warehouse rows use
account_idfor the same organization UUID. Join catalog to metrics onsoundlink_id.
Node.js:
soundlink.soundlinks.list — TypeScript SDK.
DuckDB or BigQuery: warehouse connector.