Skip to main content

Overview

The Links API allows you to manage shortened Spotify links. All write operations (create, update, delete) require authentication unless using Turnstile for anonymous link creation.

Base URL

https://api.sptfy.in/api/links
Retrieve paginated list of links owned by the authenticated user.
curl -X GET "https://api.sptfy.in/api/links?page=1&perPage=20" \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN"

Query Parameters

page
number
default:"1"
Page number for pagination
perPage
number
default:"20"
Number of items per page (max: 50)

Response

items
array
Array of link objects
page
number
Current page number
perPage
number
Items per page
totalPages
number
Total number of pages
totalItems
number
Total number of links

Example Response

{
  "items": [
    {
      "id": "abc123xyz",
      "id_url": "fk9x",
      "from": "https://open.spotify.com/track/3n3Ppam7vgaVa1iaRUc9Lp",
      "subdomain": "sptfy.in",
      "utm_view": 42,
      "enable": true,
      "user": "user_id_here",
      "created": "2024-01-15T10:30:00.000Z",
      "updated": "2024-01-15T10:30:00.000Z"
    }
  ],
  "page": 1,
  "perPage": 20,
  "totalPages": 3,
  "totalItems": 58
}

Error Responses

401
error
Authentication required - missing or invalid auth token

Create a new shortened link. Requires authentication OR a valid Turnstile token.
curl -X POST "https://api.sptfy.in/api/links" \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "https://open.spotify.com/track/3n3Ppam7vgaVa1iaRUc9Lp",
    "slug": "mytrack"
  }'

Request Body

from
string
required
Original Spotify URL to shorten (must be a valid URL)
slug
string
Custom slug for the short link. If not provided, a random slug will be generated (4-8 characters, alphanumeric).Constraints:
  • Must be unique
  • Cannot be a reserved word (e.g., “api”, “admin”, “dash”)
  • Alphanumeric characters only
subdomain
string
default:"sptfy.in"
Subdomain to use for the short link
turnstileToken
string
Cloudflare Turnstile token (required if not authenticated)

Response

Returns the created link object with status code 201 Created.
{
  "id": "new_record_id",
  "id_url": "mytrack",
  "from": "https://open.spotify.com/track/3n3Ppam7vgaVa1iaRUc9Lp",
  "subdomain": "sptfy.in",
  "utm_view": 0,
  "enable": true,
  "user": "user_id_here",
  "created": "2024-01-15T10:30:00.000Z",
  "updated": "2024-01-15T10:30:00.000Z"
}

Error Responses

400
error
Bad request - missing from parameter or invalid data
{"message": "from is required"}
409
error
Conflict - slug already taken
{"message": "slug taken"}
503
error
Service unavailable - maintenance mode active
{"message": "Service temporarily unavailable for maintenance"}

Update an existing link’s destination URL, slug, or subdomain. Requires authentication and ownership.
curl -X PATCH "https://api.sptfy.in/api/links/RECORD_ID" \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "https://open.spotify.com/track/NEW_TRACK_ID",
    "id_url": "newslug"
  }'

URL Parameters

id
string
required
PocketBase record ID of the link to update

Request Body

All fields are optional - only include fields you want to update.
from
string
New destination URL
id_url
string
New slug (must be unique)
subdomain
string
New subdomain

Response

Returns the updated link object.
{
  "id": "record_id",
  "id_url": "newslug",
  "from": "https://open.spotify.com/track/NEW_TRACK_ID",
  "subdomain": "sptfy.in",
  "utm_view": 42,
  "enable": true,
  "user": "user_id_here",
  "created": "2024-01-15T10:30:00.000Z",
  "updated": "2024-01-15T14:22:00.000Z"
}

Error Responses

401
error
Not authenticated
403
error
Forbidden - you don’t own this link
404
error
Link not found
{"message": "not found"}
409
error
Conflict - new slug already taken
{"message": "slug taken"}
400
error
Update failed
{"message": "update failed"}

Delete a link. Requires authentication and ownership.
curl -X DELETE "https://api.sptfy.in/api/links/RECORD_ID" \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN"

URL Parameters

id
string
required
PocketBase record ID of the link to delete

Response

Returns status code 204 No Content on success (empty body).

Error Responses

401
error
Authentication required
{"message": "Authentication required"}
403
error
Not authorized to delete this link
{"message": "Not authorized to delete this link"}
404
error
Link not found
{"message": "Link not found"}
500
error
Server error during deletion
{"message": "Failed to delete link"}

Delete multiple links in a single request. Maximum 5 links per request (free tier limit).
curl -X DELETE "https://api.sptfy.in/api/links/bulk" \
  -H "Authorization: Bearer YOUR_AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": ["record_id_1", "record_id_2", "record_id_3"]
  }'

Request Body

ids
array
required
Array of record IDs to delete (max 5 items)

Response

Returns a summary of the deletion operation.
{
  "deleted": ["record_id_1", "record_id_2"],
  "failed": [
    {
      "id": "record_id_3",
      "reason": "Not authorized"
    }
  ]
}
deleted
array
Array of successfully deleted record IDs
failed
array
Array of failed deletions with reasons

Error Responses

401
error
Authentication required
{"message": "Authentication required"}
400
error
Invalid request - missing/invalid ids array or exceeds limit
{"message": "Cannot delete more than 5 links at once (free tier limit)"}

Expand Spotify URL

Expand shortened Spotify URLs (spotify.link, spotify.app.link) to their final open.spotify.com destination.
curl -X POST "https://api.sptfy.in/api/expand-url" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://spotify.link/abc123"
  }'

Request Body

url
string
required
Shortened Spotify URL to expand (must be from spotify.link or spotify.app.link)

Response

{
  "expanded": "https://open.spotify.com/track/3n3Ppam7vgaVa1iaRUc9Lp",
  "original": "https://spotify.link/abc123",
  "wasExpanded": true
}
expanded
string
Final expanded URL (open.spotify.com)
original
string
Original URL that was provided
wasExpanded
boolean
Whether expansion was performed (false if already a Spotify URL)

Error Responses

400
error
Invalid URL or unsupported domain
{"message": "URL is not from a supported Spotify domain"}
500
error
Failed to expand URL
{"message": "Failed to expand URL: timeout"}

Redirect Endpoint

Access a shortened link and redirect to the original URL.

Endpoint

GET /:slug
curl -L "https://sptfy.in/abc123"

URL Parameters

slug
string
required
Short link slug (e.g., “abc123”)

Behavior

1

Lookup

System looks up the slug in the viewList collection
2

Bot Detection

Checks if the user agent is a bot/crawler (WhatsApp, Telegram, Twitter, etc.)
3

Analytics Tracking

If not a bot, creates an analytics record with:
  • User agent
  • Country (from CF-IPCountry header)
  • Timestamp
  • Link ID
4

View Count Increment

If not a bot, increments the utm_view counter in the random_short collection
5

Redirect

Issues a 301 redirect to the original URL

Response

HTTP 301 redirect to the original Spotify URL. Headers:
Location: https://open.spotify.com/track/...
Status: 301 Moved Permanently

Error Responses

404
error
Link not found
Link does not exist, but may be available in the future.
yeehaw 🔍🤠

Bot Detection

The following user agents are detected as bots and will NOT trigger analytics or view count increments:
  • whatsapp
  • telegram
  • twitter
  • bot, crawler, spider
  • facebookexternalhit
  • google-safety, google-firebase
  • okhttp, axios, node-fetch
  • python-requests
  • And more…
Bot requests are logged but do not affect analytics to prevent inflated statistics.

Build docs developers (and LLMs) love