---
title: "Spotify metadata block"
description: "How to request and read the Spotify metadata block on an AudD match: the track URI and open.spotify.com URL, preview, album artwork, and IDs."
slug: "/resources/reference/spotify"
section: "reference"
keywords: [audd, spotify metadata, spotify uri, open.spotify.com, preview, album art]
---

# Spotify metadata block

The `spotify` block attaches Spotify's own metadata for the recognized
recording to the match. It mirrors a Spotify
[Track object](https://developer.spotify.com/documentation/web-api/reference/get-track),
with the full `album` object nested inside, so you get the
`open.spotify.com` URL, the `spotify:track:…` URI, a preview, album
artwork, and track/album IDs without a second call. It is present only when
you request it — and only when Spotify has a match for the recording.

## How to request it

In the SDKs, list the provider in the `return_metadata` option (Python) /
`returnMetadata` (Node):

```python
from audd import AudD

audd = AudD("your-api-token")  # dashboard.audd.io
result = audd.recognize(
    "https://audd.tech/example.mp3",
    return_metadata=["spotify"],
)
```

```ts
import { AudD } from "@audd/sdk";

const audd = new AudD({ apiToken: "your-api-token" }); // dashboard.audd.io
const result = await audd.recognize("https://audd.tech/example.mp3", {
  returnMetadata: ["spotify"],
});
```

In raw curl, the form field is named `return` (the SDK option above is the
SDK name for the same thing):

```bash
curl https://api.audd.io/ \
  -F api_token=your-api-token \
  -F url=https://audd.tech/example.mp3 \
  -F return=spotify
```

The `market` parameter sets the country code for the Spotify lookup
(defaults to `us`); it changes which catalog entry and which
`available_markets` you get back.

## How to access it

The block is the typed `spotify` property on the result, and its sub-fields
are typed attributes on that model — attribute access, not dict subscripts.
The fields a track object carries beyond the typed ones — `external_urls`,
`preview_url`, `external_ids`, `artists`, and the nested `album` with its
`images` — round-trip through Pydantic's `model_extra` in Python / `extras`
in Node.

```python
result = audd.recognize(
    "https://audd.tech/example.mp3",
    return_metadata=["spotify"],
)
sp = result.spotify                     # None if not requested / no Spotify match
if sp:
    title = sp.name
    uri = sp.uri                        # spotify:track:… URI
    extra = sp.model_extra or {}
    page = (extra.get("external_urls") or {}).get("spotify")  # open.spotify.com URL
    preview = extra.get("preview_url")  # 30s MP3 preview (may be null)
    album = extra.get("album") or {}
    cover = (album.get("images") or [{}])[0].get("url")       # largest cover first
```

```ts
const sp = result.spotify;              // undefined if not requested / no match
if (sp) {
  const uri = sp.uri;
  const page = sp.external_urls?.spotify;   // open.spotify.com URL (via extras)
  const cover = sp.album?.images?.[0]?.url; // largest cover first
}
```

Notes on a couple of fields:

- `album.images[]` is ordered largest first (typically 640, 300, 64). Pick
  `album.images[0].url` for the biggest, or match on `width`.
- `preview_url` is a 30-second MP3 preview, but Spotify returns `null` for
  some tracks — check before using it, and honor Spotify's terms.

## Fields

The typed fields on the Spotify block:

| Field | Type | Description |
|---|---|---|
| `id` | string \| null | Spotify track ID. |
| `name` | string \| null | Track title. |
| `uri` | string \| null | `spotify:track:…` URI, the form the Web Playback SDK expects. |
| `duration_ms` | int \| null | Track length in milliseconds. |
| `track_number` | int \| null | Position on the album. |
| `explicit` | bool \| null | Whether the track is flagged explicit. |
| `popularity` | int \| null | Spotify's 0–100 popularity score. |
| `type` | string \| null | Object type (`track`). |

The richer parts of a Spotify track object — `external_urls.spotify`,
`preview_url`, `external_ids.isrc`, `artists[]`, and the nested `album`
(with `images[]`, `release_date`, IDs) — aren't typed properties; read them
through the block's `model_extra` (Python) / `extras` (Node). For the full
track and album schema see Spotify's
[Track object reference](https://developer.spotify.com/documentation/web-api/reference/get-track).

The block and every field can be absent or null — request did not include
`spotify`, no Spotify match for the recording, or the provider omitted a
field. Always null-check before reading.

## Without requesting the block: `song_link`

You don't need the `spotify` block just to send a user to Spotify. Every
match carries a `song_link` (a lis.tn URL such as `https://lis.tn/NbkVb`),
and the `streaming_url("spotify")` SDK helper (`streamingUrl("spotify")` in
Node) returns an "open in Spotify" redirect built from it — no provider
block, no added latency:

```python
result.streaming_url("spotify")   # lis.tn ?spotify redirect
```

Request the `spotify` block when you need the structured metadata — the
`open.spotify.com` URL or URI, track/album IDs, preview, artwork — in your
own UI. See the [lis.tn song link](/resources/concepts/lisn-song-link)
concept for the redirect convention.

---

**Related**

- [Apple Music metadata block](/resources/reference/apple-music)
- [Deezer metadata block](/resources/reference/deezer)
- [MusicBrainz metadata block](/resources/reference/musicbrainz)
- [The lis.tn song link](/resources/concepts/lisn-song-link)
- [Provider metadata overview](/resources/reference/provider-metadata)