# How to Integrate the SpotifySaver API with External Applications Using REST Endpoints

> Easily integrate the SpotifySaver API using FastAPI REST endpoints. Trigger Spotify downloads, monitor progress, and fetch metadata with simple HTTP requests. Learn how today.

- Repository: [Gabriel Baute/spotify-saver](https://github.com/gabrielbaute/spotify-saver)
- Tags: api-reference
- Published: 2026-03-02

---

**The SpotifySaver API provides FastAPI-based REST endpoints that allow external applications to trigger downloads, monitor task progress, and retrieve Spotify metadata via standard HTTP requests.**

The SpotifySaver API is the REST interface for the `gabrielbaute/spotify-saver` repository, exposing a stateless HTTP layer over the core download engine. Built on FastAPI and served by Uvicorn, it enables third-party automation, CI/CD pipelines, or frontend applications to programmatically convert Spotify tracks, albums, and playlists into local audio files without interacting with the CLI directly.

## API Architecture and Entry Points

The server bootstrap logic resides in [`spotifysaver/api/main.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/main.py), where the FastAPI application is instantiated and executed:

```python
app = create_app()                     # FastAPI instance built via factory

uvicorn.run(
    "spotifysaver.api.main:app",
    host=APIConfig.API_HOST,
    port=APIConfig.API_PORT,
    reload=True,
    log_level=APIConfig.LOG_LEVEL,
)

```

The `create_app()` factory in [`spotifysaver/api/app.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/app.py) configures Cross-Origin Resource Sharing (CORS) using `APIConfig.ALLOWED_ORIGINS`, mounts static UI assets, and registers the download router under the `/api/v1` prefix. Centralized configuration defaults are stored in [`spotifysaver/api/config.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/config.py), including host, port, and output directory settings.

## REST Endpoint Reference

All public REST endpoints are defined in [`spotifysaver/api/routers/download.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/routers/download.py) and mounted at `/api/v1`. The router exposes the following operations:

| HTTP Method | Path | Purpose | Implementation Function |
|-------------|------|---------|-------------------------|
| **POST** | `/api/v1/download` | Initiates a download job for a track, album, or playlist. Returns a `task_id`. | `start_download` (lines 33–84) |
| **GET** | `/api/v1/download/{task_id}/status` | Retrieves current job status: `pending`, `processing`, `completed`, or `failed`. | `get_download_status` (lines 90–96) |
| **GET** | `/api/v1/download/{task_id}/cancel` | Cancels a running job if it has not finished. | `cancel_download` (lines 99–114) |
| **GET** | `/api/v1/downloads` | Lists all tasks categorized into `completed`, `pending`, and `processing`. | `list_downloads` (lines 117–138) |
| **GET** | `/api/v1/inspect` | Returns Spotify metadata (title, artists, duration) without downloading files. | `inspect_spotify_url` (lines 141–199) |
| **GET** | `/api/v1/config/output_dir` | Exposes the default output directory configured in `APIConfig`. | `get_default_output_dir` (lines 55–58) |

The `start_download` endpoint accepts a JSON body matching the `DownloadRequest` Pydantic schema and delegates execution to `DownloadService` via FastAPI's `BackgroundTasks`, ensuring the HTTP response returns immediately while processing continues asynchronously.

## Data Contracts and Schemas

Type safety and automatic API documentation are enforced through Pydantic models located in [`spotifysaver/api/schemas.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/schemas.py):

* **`DownloadRequest`** – Defines the POST body for `/download`, including `spotify_url`, `output_format`, `bit_rate`, `output_dir`, and boolean flags for lyrics and cover art.
* **`DownloadResponse`** – Returned upon job creation, containing `task_id`, `status`, `content_type`, and a human-readable `message`.
* **`DownloadStatus`** – Polling payload with `progress` percentage, `current_track`, and detailed status fields.
* **`TrackInfo`**, **`AlbumInfo`**, **`PlaylistInfo`** – Metadata structures returned by the `/inspect` endpoint.

These schemas generate the interactive OpenAPI documentation accessible at `/docs` when the server is running.

## Integration Examples

### Start a Download via cURL

```bash
curl -X POST http://localhost:8000/api/v1/download \
  -H "Content-Type: application/json" \
  -d '{
        "spotify_url": "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
        "download_lyrics": true,
        "download_cover": true,
        "generate_nfo": false,
        "output_format": "mp3",
        "bit_rate": 256,
        "output_dir": "/tmp/music"
      }'

```

**Expected Response:**

```json
{
  "task_id": "a3f1c9e2-4d7b-48b5-9e6d-2b7c9fa5e3d1",
  "status": "pending",
  "spotify_url": "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
  "content_type": "playlist",
  "message": "Download task started for playlist"
}

```

### Poll Task Status with Python Requests

```python
import time
import requests

BASE_URL = "http://localhost:8000/api/v1"
TASK_ID = "a3f1c9e2-4d7b-48b5-9e6d-2b7c9fa5e3d1"

while True:
    response = requests.get(f"{BASE_URL}/download/{TASK_ID}/status")
    status = response.json()
    
    print(f"[{status['status']}] {status['progress']}% – {status.get('current_track', 'N/A')}")
    
    if status["status"] in ("completed", "failed"):
        break
    time.sleep(2)

```

### Inspect Metadata Without Downloading

```bash
curl "http://localhost:8000/api/v1/inspect?spotify_url=https://open.spotify.com/track/2kd0T6zgABT8P0s2h9QU5O"

```

**Response Structure:**

```json
{
  "name": "Song Title",
  "artists": ["Artist One", "Artist Two"],
  "album_name": "Album Name",
  "duration": 212,
  "number": 1,
  "uri": "spotify:track:2kd0T6zgABT8P0s2h9QU5O"
}

```

### Cancel a Running Job

```bash
curl -X GET http://localhost:8000/api/v1/download/a3f1c9e2-4d7b-48b5-9e6d-2b7c9fa5e3d1/cancel

```

### List All Tasks

```bash
curl http://localhost:8000/api/v1/downloads

```

## Summary

- The **SpotifySaver API** exposes FastAPI-based REST endpoints under `/api/v1` for programmatic control of Spotify downloads.
- **Entry point**: [`spotifysaver/api/main.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/main.py) bootstraps the Uvicorn server, while [`spotifysaver/api/app.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/app.py) configures CORS and mounts the download router.
- **Core router**: [`spotifysaver/api/routers/download.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/routers/download.py) implements six primary endpoints: `POST /download`, `GET /download/{task_id}/status`, `GET /download/{task_id}/cancel`, `GET /downloads`, `GET /inspect`, and `GET /config/output_dir`.
- **Data models**: [`spotifysaver/api/schemas.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/schemas.py) defines Pydantic schemas (`DownloadRequest`, `DownloadResponse`, `DownloadStatus`) that enforce type safety and auto-generate OpenAPI documentation at `/docs`.
- **Async processing**: Downloads run as FastAPI `BackgroundTasks` via `DownloadService` in [`spotifysaver/api/services/download_service.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/services/download_service.py), allowing immediate HTTP responses while processing continues server-side.

## Frequently Asked Questions

### How do I authenticate requests to the SpotifySaver API?

The current implementation in `gabrielbaute/spotify-saver` does not enforce authentication or API keys on its REST endpoints. The API is designed for local or trusted network deployments where the FastAPI instance runs behind a firewall or reverse proxy. For production exposure, you should implement OAuth2, API key headers, or network-level authentication (VPN, IP whitelisting) as the underlying code does not provide built-in auth mechanisms.

### What Spotify content types can I download through the API?

According to the `start_download` implementation in [`spotifysaver/api/routers/download.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/routers/download.py), the API accepts Spotify URLs for **individual tracks**, **full albums**, and **public playlists**. The `inspect_spotify_url` endpoint returns distinct metadata schemas for each type (`TrackInfo`, `AlbumInfo`, `PlaylistInfo` in [`spotifysaver/api/schemas.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/schemas.py)), confirming support for all three content categories.

### How does the API handle concurrent download jobs?

The API leverages FastAPI's `BackgroundTasks` system to handle concurrency. When you POST to `/api/v1/download`, the `start_download` function immediately returns a `task_id` and delegates the heavy processing to `DownloadService` via `background_tasks.add_task()`. This allows the server to accept multiple simultaneous jobs; however, the current in-memory task registry in [`download_service.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/download_service.py) is not persistent. For high-concurrency production use, you should replace the in-memory store with Redis or a database to prevent task loss on server restarts.

### Can I retrieve metadata without downloading files?

Yes. The `GET /api/v1/inspect` endpoint, implemented in [`spotifysaver/api/routers/download.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/routers/download.py) as the `inspect_spotify_url` function, returns full metadata for any Spotify URL without triggering a download. It accepts a `spotify_url` query parameter and returns JSON structures defined in [`spotifysaver/api/schemas.py`](https://github.com/gabrielbaute/spotify-saver/blob/main/spotifysaver/api/schemas.py) (`TrackInfo`, `AlbumInfo`, or `PlaylistInfo`), including track names, artist lists, album details, and Spotify URIs.