Skip to the content

Spotify Library Import API: Shipping an Import Flow Under 2026 Development Mode Limits

Spotify Library Import API: Shipping an Import Flow Under 2026 Development Mode Limits

If you are scoping a Spotify library import API for your own onboarding, the gate is not your code. It is the quota mode Spotify puts your client in. Development Mode use now requires a Spotify Premium account, and each Client ID is limited to up to five authorized users. Five listeners, each one allowlisted by hand. That is enough to demo an import to your own team and nothing else. What follows is the version a product team needs: what Development Mode can and cannot do after the February and July 2026 changes, what the extended quota bar asks of a company, and what the import flow looks like when read access is the gate rather than the wizard.

The three access paths, side by side

PathWho can authorizeThe real constraint
Spotify Development ModeUp to five authorized users per Client IDOwner needs Premium, every user allowlisted, quota counted per developer account
Spotify extended quota modeUnlimited installs, the allowlist stops applyingRegistered business, launched service, at least 250k MAUs, review up to six weeks
MusicAPIAny listener who authorizes a transferMetered per request to the streaming service, EUR 500 per month minimum

The rest of this post is the detail behind those three rows.

What Development Mode allows after the 2026 changes

Spotify moved twice this year. In February it announced that starting Wednesday 11 February, all newly created Development Mode Client IDs would be created under updated rules. The defaults: Premium required, one Client ID per developer, up to five authorized users per Client ID, and API access limited to a smaller set of supported endpoints. From March 9, Spotify said the same requirements would also apply to existing Development Mode integrations. Spotify later postponed the endpoint access changes for existing integrations, while the Premium requirement, the authorized user cap and the one Client ID per developer limit took effect as planned.

July 23 loosened one number and tightened another. The Client ID limit rose from 1 to 25 per developer account. In the same update, quota counting moved to the developer account rather than the Client ID, so all your Development Mode Client IDs share a single quota. Twenty five clients do not buy you twenty five budgets. If you run multiple Development Mode Client IDs, they now draw from the same quota pool. Endpoints are grouped into quota buckets, and requests to endpoints in the same bucket count toward a shared limit.

Two operational details matter more than they look. Premium is a live dependency: if the owner's Premium subscription lapses, the app stops working. And the allowlist is manual, because each Spotify user who installs your app has to be added to the allowlist before they can use it. A request carrying a token for a user who was never allowlisted returns a 403 status code error.

When the quota is exceeded, the 429 response now carries a structured reason field, and Spotify's own guidance is to use it to distinguish quota limits from rate limits and pace usage accordingly. If you already handle provider throttling, that is one more branch in code you have. Our guide to music API rate limiting across streaming services covers the backoff shape this needs.

Spotify states the intent plainly. Development Mode is intentionally limited and should not be relied on as a foundation for building or scaling a business on Spotify.

The extended quota bar is a company test, not a code test

Extended quota mode is the path that actually serves listeners. Apps in that category can be installed by an unlimited number of users, and the development mode allowlist no longer applies. The implementation requirements are a business checklist, not an engineering one: an established business entity, an active and launched service, a minimum of active users (at least 250k MAUs), availability in key Spotify markets, commercial viability and adherence to terms. Since May 15th 2025, Spotify only accepts applications from organizations, not individuals, and the application goes through a company email form. The review can take up to six weeks.

The 2025 criteria update gives the rest of the picture. Extended Web API access is reserved for apps with established, scalable, and impactful use cases, and Spotify reported that over 95% of applications it received fell short of basic security, privacy, and licensing standards. Apps already in extended quota mode need no migration and keep their existing endpoints, fields and behaviors.

So the sequencing problem is real. The import feature is often the thing meant to grow your MAU, and the access tier that would let it run wants the MAU first. That is the gap MusicAPI fills: we hold the Spotify credentials and use them only to move a listener's own library on their behalf, so there is no developer account, no OAuth client and no refresh loop on your side. See the Spotify API integration page for the endpoint list.

What the February migration guide changed in the read path

If you do build directly and stay in Development Mode, the import code you find in older tutorials no longer matches the live API. The changes that hit a library read:

  • Batch fetch endpoints are gone. The guide says the batch endpoints are no longer available and to fetch items individually instead. One request per track instead of one batch request.
  • Playlist track management endpoints were renamed from /tracks to /items, and the playlist response field renamed with them.
  • Playlist contents are only returned for playlists the user owns or collaborates on. Followed playlists return metadata only, so "import everything in my library" quietly becomes "import what the listener owns".
  • Search got smaller. If your app relies on fetching more than 10 results per search request, you now paginate with offset.
  • Other users are off the table. GET /users/{id}/playlists has no replacement and you use GET /me/playlists for the current user.
  • Several response fields were removed, and the guide tells you to update your code to handle their absence gracefully.

Write side, for completeness: the entity type specific save, remove, follow and unfollow endpoints were replaced with generic library endpoints that work with Spotify URIs. An import out of Spotify reads, so that matters only if you also push content back.

Paging a Spotify library is where the requests go

The liked songs read is GET /me/tracks, which returns a list of the songs saved in the current Spotify user's Your Music library. The paging envelope is standard: limit defaults to 20 with a maximum of 50, offset is the index of the first item to return and you use it with limit to get the next set of items, next is the URL to the next page and null when there is none, and total is the number of items available.

GET /v1/me/tracks?limit=50&offset=0
Authorization: Bearer <user access token>

Each item carries added_at, the date and time the track was saved, which is what you need if you want the import to preserve library order. One more trap: if neither market nor the user country is provided, the content is considered unavailable for the client, so a naive call can return a library that looks empty.

Now do the arithmetic against the quota. A 200,000 item library at 50 items per page is 4,000 requests for liked tracks alone, before playlists, before albums, and before the per track hydration that the removal of batch endpoints forces. All of it counts against one per account budget. For the general pattern, see music API pagination for large libraries, and for the normalized version of this read, the get favorite tracks endpoint for Spotify and the Spotify user playlists endpoint.

GET https://api.musicapi.com/api/{userUUID}/liked/tracks
Authorization: Basic <clientId:clientSecret>

That route gives full paged access to liked tracks, albums and followed artists in Spotify, and the same shape answers for the other services on the schema.

Matching decides whether the import looks finished

Reading Spotify is the easy half. Writing those recordings into your catalogue is where listeners judge you. Spotify's saved track object carries external IDs on the track:

"external_ids": { "isrc": "string", "ean": "string", "upc": "string" }

That ISRC is your first key. It will not cover everything, because regional catalogue differences, compilations and local files break clean identity. MusicAPI resolves a track, album or artist to its Spotify ID by ISRC or by text with a confidence score, and regional catalogue differences are resolved by ISRC first, then by our fuzzy resolver. Podcast and audiobook objects are out of scope. If you want the matching theory before you write your own, read working with ISRCs and cross-platform matching.

Per-item results your backend can act on

An import that reports "done" and loses 3% of a library silently will generate support tickets. Webhooks are how your backend follows a transfer. The useful ones for an onboarding import:

  • transfer.created fires once the source library has been read, so totalItems is a real number rather than an estimate. That is the number your progress UI should trust.
  • transfer.progress is sent at most once every 15 seconds per transfer, plus at each 10% step.
  • transfer.item_failed means items of one collection could not be written, with up to 50 items per delivery.
  • match.report_ready carries resultsUrl, the Match Results API address of the unmatched items of this transfer.

Read the counters precisely. matchedItems counts what we added and skippedItems what the destination already had, so a re-run reports mostly skips. The hosted flow ends on a live progress page, then a results page with match rates, unmatched items and a CSV export. The webhook documentation has every event shape.

When the listener is already signed in to your app

For an onboarding import, your own service is the destination and the listener is usually already authenticated with you. Pre-authorized sessions cover that: your backend calls POST /public/transfer-sessions with the user's token, we check the token with the music service, store it encrypted and answer with a launchUrl. The pre-authorized sessions documentation has the request and response shapes. The launchUrl works once, and only for 15 minutes, so create the session when the listener taps the import button. The destination must be one of Spotify, Deezer, Tidal, YouTube, SoundCloud or Boomplay, the services that use a plain OAuth access token, and for other destinations the endpoint answers 400. If the token dies mid transfer you get user.auth_failed, your backend pushes a new token with PUT /public/transfer-sessions/{sessionUuid}/target-auth, and the transfer continues. The progress page tells the listener that your app renews the connection, and it does not ask them to log in to the destination. For the surrounding UX decisions, see designing an import flow listeners can finish.

Build versus buy, with the access gate priced in

Building directly means a developer account, app review and quota requests per service, plus your own OAuth client, token storage and refresh, and a changelog to track. The February and July 2026 changes are the evidence: two rounds of endpoint and quota edits in five months, both landing on Development Mode integrations. MusicAPI is one key, all 12 services, live in minutes, with standardised 429s carrying Retry-After plus retries and idempotency built in. A sandbox key is instant and reading a live library takes about an hour, and production integrations typically land in two to four engineering weeks. Billing is per request to a music service: EUR 0.60 per 1,000 for the first 5M, EUR 0.45 up to 25M, EUR 0.30 above that, with a EUR 500 per month minimum. The pricing page has the calculator. If you need a Spotify field we do not normalize, passthrough gives you that listener's underlying Spotify token when your transfer flow needs it.

Skip months of OAuth and per-provider integration work. Sandbox keys are free and instant, and one API moves libraries between 12 streaming services.

FAQ

Can I serve 125 listeners by creating 25 Development Mode Client IDs?

No, and do not design for it. The five user cap applies per Client ID, but quota counting is per developer account and all your Development Mode Client IDs share a single quota. Spotify also states that Development Mode should not be relied on as a foundation for building or scaling a business.

My app already has more than five users. Do we lose them?

Existing apps are grandfathered: if you already have multiple Client IDs or more than 5 users, you retain them. The limits restrict what you can create or add going forward. The Premium requirement still applies to existing Development Mode integrations.

Does extended quota mode help with rate limits as well as user counts?

Yes. Extended quota mode apps have access to a higher rate limit than development mode apps do, on top of unlimited installs. Our post on API rate limits across music streaming services covers how that interacts with the other providers.

Can we prototype the import before we qualify for extended access?

Yes. Newly created apps begin in development mode, which suits apps under construction, and that is fine for a prototype against your own account. A sandbox key is instant and reading a live library takes about an hour, and because the sandbox is capped at 5 test listeners in total, putting the flow in front of real listeners means production use with a EUR 500 per month minimum.