pivotintegrationspotifylastfmfast-iterationultra-lab

30 Minutes from Spotify to Last.fm — A Story About Pivoting When Assumptions Fail

· 31 min read

30 Minutes from Spotify to Last.fm — A Story About Pivoting When Assumptions Fail

Writing this from the plane. Earlier today at 10:46 PM Taipei time, waiting at Gate C2, I added a "Now Playing" panel to Atlas — showing what I'm listening to in real time. The original plan was Spotify integration.

Within an hour I had ripped it all out and switched to Last.fm.

The process was short, but there are 3 decision points worth recording. Here goes.


The plan: Spotify Web API

Atlas's "Now Playing" needs to show what I'm currently listening to. Spotify has a formal API:

GET /v1/me/player/currently-playing

OAuth once to get a refresh_token, then server-side automatically refresh the access_token, then poll every 60 seconds.

The design was clean. I wrote 200+ lines of TypeScript:

  • /api/spotify?action=connect — redirect to Spotify authorize
  • /api/spotify?action=callback — exchange OAuth code, store refresh_token in Firestore
  • /api/spotify?action=now — use refresh_token to fetch currently-playing track

Wrote it, deployed it, told the user to create an app on Spotify Developer Dashboard.


First failure: Spotify gates Web API behind Premium

The user sent me a screenshot: he can't check the "Web API" checkbox; a banner across the top says "Upgrade to Spotify Premium to access the Web API."

This wasn't my fault — but it was my blind spot.

Spotify changed Web API access to Premium-only somewhere in late 2024. I wrote the integration without checking current policy.

The user is on Spotify free. The whole architecture is unusable.

Decision time: 30 seconds. Two options:

  • A. Have the user upgrade to Premium ($11/month, may not be willing)
  • B. Pivot to a different solution

Picked B.


Second failure: Vercel function count limit

Immediately thought of Last.fm. Its API:

  • No Premium required
  • Public read (with an API key, you can query any user's recent tracks)
  • Cross-platform (Last.fm scrobbler integrates with Spotify, Apple Music, YouTube Music)
  • CORS-friendly

But then a second problem surfaced: the earlier Spotify push had failed deploy. Vercel returned "function count" error in red.

UltraLab is on Vercel Hobby plan, 12 function limit. I'd pushed Spotify, making it 14.

Hobby plan doesn't allow upgrading function count.

Decision time: 1 minute.

  • Upgrade to Pro plan ($20/month) — overkill for 1 endpoint
  • Drop the Spotify endpoint and use Last.fm purely client-side (CORS direct fetch) — no endpoint needed

Chose the latter. Coincidentally the pivot to Last.fm also saves an endpoint, making it cleaner.


Third discovery: Last.fm is actually better

Writing the Last.fm integration, I realized it's better suited to this use case than Spotify:

Dimension Spotify Last.fm
Premium required Yes No (free)
Cross-platform Spotify-only Connects to Spotify / Apple Music / YouTube Music / etc.
OAuth complexity refresh_token + backend API key + pure frontend
Server-side requirement Endpoint needed None
API CORS Configure Friendly by default
Historical access Closed Open (recent tracks)

Last.fm has been running since 2002. The UI is dated but the API is shockingly stable.

The only trade-off: the user needs to install a Last.fm scrobbler app and connect Spotify. 5 minutes of setup.

30 minutes later, the entire Atlas "Now Playing" panel was running — showing the user listening to Mac Miller's "I Can See."


Full timeline

  • 22:38 user says "I have Spotify," start Spotify integration plan
  • 22:39-22:50 I write 200+ lines of TypeScript spotify.ts
  • 22:51 push deploy → ❌ Vercel function count exceeded
  • 22:52 user screenshot: Spotify Web API requires Premium
  • 22:53 decision to pivot to Last.fm
  • 22:54-23:08 write Last.fm pure frontend integration
  • 23:08 user sets up Last.fm account + connects Spotify
  • 23:09 I set Vercel env vars, redeploy
  • 23:11 Atlas shows the user is listening to Mac Miller — "I Can See"

From "decide to pivot" to "first track displayed": 18 minutes.


Lessons

1. Check current policy before integrating an API.

Spotify's Premium gating wasn't hidden — there's a banner on Developer Dashboard. I didn't spend 5 minutes reading before writing code. Cost: 1 wasted hour.

2. "Failure indicators" should be fast.

I was halfway through OAuth code when Vercel's hard limit stopped me. That hard limit became my forcing function for re-evaluating the approach.

Structurally: limits are good. If Spotify hadn't gated free accounts and Vercel hadn't had a 12-function limit, I might have completed the integration but with a worse design.

3. The first solution isn't the best solution.

Spotify was the "looks legitimate" choice — big platform, official API, formal refresh_token flow.

Last.fm was the "looks ancient" choice — UI from 2002, ugly docs.

But for my use case (public read of my own currently playing), Last.fm cross-platform + no OAuth + no backend completely beats Spotify.

I'll be more open to evaluating "looks old" options going forward.


What you can take away

If you're building a similar "real-time listening" / "what I'm doing right now" integration:

  • Last.fm > Spotify Web API for public-read use cases, still true in 2026
  • CORS-friendly API > backend-OAuth API, every endpoint you save is one less failure point
  • Vercel Hobby's 12-function limit is a forcing function — pushes you to evaluate pure frontend approaches
  • "Pivot looks like loss" but the failed solution would have had problems anyway. Earlier discovery = more saved time.

Atlas's Now Playing source code is open source, ~150 lines, no backend, fork it and change the username to use it yourself.


Part 4 of 5 in the "Min Yi in Germany Atlas" public-experiment series. Next: Crypto Agent 21-incident tracker launches.

Written 2026-05-08, 1.5 hours into BR71 flight.

Weekly AI Automation Playbook

No fluff — just templates, SOPs, and technical breakdowns you can use right away.

Join the Solo Lab Community

Free resource packs, daily build logs, and AI agents you can talk to. A community for solo devs who build with AI.

Need Technical Help?

Free consultation — reply within 24 hours.