Syncify copies your Spotify "Liked Songs" to a regular playlist that can be made public and shared with friends. Spotify has never offered this natively, so here we are.
It syncs automatically every 24 hours. You can also trigger a sync manually at any time.
Live at syncify.keval6b.com
- Log in with Spotify and grant access
- Press "Enqueue Sync" to copy your liked songs into a playlist (or wait for the automatic 24-hour sync)
- Find your new playlist in your Spotify library
Playlists are matched by name, so renaming one causes a fresh playlist to be created on the next sync, which is useful for keeping snapshots.
Fully serverless on AWS, running at roughly $1-5/month.
- Frontend — React SPA (Vite, TanStack Router/Query) deployed to S3 behind CloudFront
- API — FastAPI + Mangum on Lambda (arm64), behind API Gateway HTTP API (rate limited: 20 req/s, burst 50), JWT cookie sessions
- Worker — separate Lambda with reserved concurrency of 1, triggered by SQS
- Scheduling — one EventBridge Schedule per user (rate 24h) feeds the SQS queue automatically; created on signup and deleted on account deletion or revoked Spotify access
- Database — DynamoDB; sync request history expires after 1 year via TTL
- IaC — Terraform in
infra/ - CI/CD — PRs run
pytest. Push tomainauto-deploys staging, then production waits on theprdGitHub Environment approval. OIDC, no stored AWS keys.
- AWS account
- Spotify app (create one here) with a redirect URI you will add after the first deploy
- Terraform >= 1.9
- A GitHub repo with Actions enabled
Create an S3 bucket in your target region for Terraform state, then update the bucket, key, and region in infra/versions.tf.
Create an IAM role trusted by GitHub Actions OIDC (token.actions.githubusercontent.com) and scoped to your repository. The production apply job uses the prd environment; staging auto-apply uses stg. The deploy role's trust policy must allow both repo:OWNER/REPO:environment:prd and repo:OWNER/REPO:environment:stg. Attach the following AWS managed policies:
AWSLambda_FullAccessAmazonAPIGatewayAdministratorAmazonDynamoDBFullAccessAmazonSQSFullAccessAmazonS3FullAccessCloudFrontFullAccessAmazonEventBridgeFullAccessAmazonEventBridgeSchedulerFullAccessCloudWatchFullAccessAmazonSNSFullAccess
For IAM (needed to manage Lambda execution roles), attach a custom policy scoped to arn:aws:iam::*:role/syncify-* covering iam:CreateRole, iam:DeleteRole, iam:GetRole, iam:TagRole, iam:PutRolePolicy, iam:DeleteRolePolicy, iam:GetRolePolicy, iam:ListRolePolicies, iam:ListAttachedRolePolicies, and iam:PassRole (the latter conditioned on iam:PassedToService of lambda.amazonaws.com and scheduler.amazonaws.com).
Create a prd environment (required reviewers) and a stg environment (no reviewers) in your GitHub repo settings. Add the following to repository variables / the prd environment as you already do:
| Secret | Description |
|---|---|
AWS_DEPLOY_ROLE_ARN |
ARN of the deploy role created above |
SPOTIPY_CLIENT_ID |
Spotify app client ID |
SPOTIPY_CLIENT_SECRET |
Spotify app client secret |
JWT_SECRET |
Secret for signing session cookies; generate with openssl rand -hex 32 |
POSTHOG_API_KEY |
PostHog API key (optional; used for both frontend analytics and server-side event capture) |
Push to main. GitHub Actions runs the test suite, publishes a Lambda layer, auto-applies the staging stack (syncify-stg-*, backend key syncify-stg/terraform.tfstate), and syncs a PostHog-free frontend to the staging bucket. Production uses the same commit: it plans against the prod state, then waits for prd environment approval before apply and a PostHog-keyed frontend sync.
PRs run tests only; they do not deploy.
scripts/deploy-stg.sh is still available for a local staging push from a dirty tree.
- Custom domain — add your domain and ACM certificate to the CloudFront distribution in the AWS console; Terraform is configured to ignore these fields on subsequent deploys
- Spotify redirect URI — register
https://your-domain.com/api/v1/auth/callbackin your Spotify app's settings - SNS alerts — subscribe to the
syncify-alarmsSNS topic in AWS to receive email alerts for Lambda errors and worker failures