or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdbrowse.mdcache.mdclient.mdindex.mdplayback.mdplaylists.mdpodcasts.mduser-library.md

playlists.mddocs/

0

# Playlist Management

1

2

Comprehensive playlist operations including creation, modification, track management, collaboration features, and following functionality. Supports both current user's playlists and operations on other users' public playlists.

3

4

## Capabilities

5

6

### Playlist Information

7

8

Retrieve playlist details and metadata.

9

10

```python { .api }

11

def playlist(self, playlist_id, fields=None, market=None, additional_types=("track",)):

12

"""

13

Get playlist information.

14

15

Args:

16

playlist_id (str): Spotify playlist ID or URI

17

fields (str, optional): Comma-separated list of fields to return

18

market (str, optional): ISO 3166-1 alpha-2 country code

19

additional_types (tuple): Include 'episode' for podcast episodes (default: ("track",))

20

21

Returns:

22

dict: Playlist object with tracks, metadata, and owner information

23

"""

24

25

def current_user_playlists(self, limit=50, offset=0):

26

"""

27

Get current user's playlists.

28

29

Requires scope: playlist-read-private

30

31

Args:

32

limit (int): Number of playlists to return (1-50, default: 50)

33

offset (int): Index of first playlist (default: 0)

34

35

Returns:

36

dict: Paging object of simplified playlist objects

37

"""

38

39

def user_playlists(self, user, limit=50, offset=0):

40

"""

41

Get user's public playlists.

42

43

Args:

44

user (str): Spotify user ID

45

limit (int): Number of playlists to return (1-50, default: 50)

46

offset (int): Index of first playlist (default: 0)

47

48

Returns:

49

dict: Paging object of simplified playlist objects

50

"""

51

```

52

53

### Playlist Items and Tracks

54

55

Access and retrieve playlist content.

56

57

```python { .api }

58

def playlist_items(self, playlist_id, fields=None, limit=100, offset=0,

59

market=None, additional_types=("track", "episode")):

60

"""

61

Get playlist items (tracks and episodes).

62

63

Args:

64

playlist_id (str): Spotify playlist ID or URI

65

fields (str, optional): Comma-separated list of fields to return

66

limit (int): Number of items to return (1-100, default: 100)

67

offset (int): Index of first item (default: 0)

68

market (str, optional): ISO 3166-1 alpha-2 country code

69

additional_types (tuple): Content types to include (default: ("track", "episode"))

70

71

Returns:

72

dict: Paging object of playlist track objects with added_by and added_at info

73

"""

74

75

def playlist_tracks(self, playlist_id, fields=None, limit=100, offset=0,

76

market=None, additional_types=("track",)):

77

"""

78

Get playlist tracks (legacy method, use playlist_items instead).

79

80

Args:

81

playlist_id (str): Spotify playlist ID or URI

82

fields (str, optional): Comma-separated list of fields to return

83

limit (int): Number of tracks to return (1-100, default: 100)

84

offset (int): Index of first track (default: 0)

85

market (str, optional): ISO 3166-1 alpha-2 country code

86

additional_types (tuple): Content types to include (default: ("track",))

87

88

Returns:

89

dict: Paging object of playlist track objects

90

"""

91

92

def user_playlist(self, user, playlist_id=None, fields=None, market=None):

93

"""

94

Get user playlist (legacy method, use playlist instead).

95

96

Args:

97

user (str): Spotify user ID (ignored in current API)

98

playlist_id (str): Spotify playlist ID or URI

99

fields (str, optional): Comma-separated list of fields to return

100

market (str, optional): ISO 3166-1 alpha-2 country code

101

102

Returns:

103

dict: Playlist object

104

"""

105

106

def user_playlist_tracks(self, user, playlist_id, fields=None, limit=100,

107

offset=0, market=None):

108

"""

109

Get user playlist tracks (legacy method, use playlist_tracks instead).

110

111

Args:

112

user (str): Spotify user ID (ignored in current API)

113

playlist_id (str): Spotify playlist ID or URI

114

fields (str, optional): Comma-separated list of fields to return

115

limit (int): Number of tracks to return (1-100, default: 100)

116

offset (int): Index of first track (default: 0)

117

market (str, optional): ISO 3166-1 alpha-2 country code

118

119

Returns:

120

dict: Paging object of playlist track objects

121

"""

122

```

123

124

### Playlist Creation and Modification

125

126

Create new playlists and modify existing ones.

127

128

```python { .api }

129

def user_playlist_create(self, user, name, public=True, collaborative=False, description=""):

130

"""

131

Create playlist for user (legacy method).

132

133

Requires scope: playlist-modify-public or playlist-modify-private

134

135

Args:

136

user (str): Spotify user ID (must be current user)

137

name (str): Playlist name

138

public (bool): Make playlist public (default: True)

139

collaborative (bool): Make playlist collaborative (default: False)

140

description (str): Playlist description (default: "")

141

142

Returns:

143

dict: Created playlist object

144

"""

145

146

def playlist_change_details(self, playlist_id, name=None, public=None,

147

collaborative=None, description=None):

148

"""

149

Change playlist details.

150

151

Requires scope: playlist-modify-public or playlist-modify-private

152

153

Args:

154

playlist_id (str): Spotify playlist ID or URI

155

name (str, optional): New playlist name

156

public (bool, optional): Make playlist public/private

157

collaborative (bool, optional): Make playlist collaborative

158

description (str, optional): New playlist description

159

160

Returns:

161

None

162

"""

163

164

def user_playlist_change_details(self, user, playlist_id, name=None, public=None,

165

collaborative=None, description=None):

166

"""

167

Change user playlist details (legacy method, use playlist_change_details instead).

168

169

Requires scope: playlist-modify-public or playlist-modify-private

170

171

Args:

172

user (str): Spotify user ID (ignored in current API)

173

playlist_id (str): Spotify playlist ID or URI

174

name (str, optional): New playlist name

175

public (bool, optional): Make playlist public/private

176

collaborative (bool, optional): Make playlist collaborative

177

description (str, optional): New playlist description

178

179

Returns:

180

None

181

"""

182

```

183

184

### Adding Items to Playlists

185

186

Add tracks and episodes to playlists.

187

188

```python { .api }

189

def playlist_add_items(self, playlist_id, items, position=None):

190

"""

191

Add items to playlist.

192

193

Requires scope: playlist-modify-public or playlist-modify-private

194

195

Args:

196

playlist_id (str): Spotify playlist ID or URI

197

items (list): List of track/episode URIs to add (max 100)

198

position (int, optional): Position to insert items (default: end)

199

200

Returns:

201

dict: Object with snapshot_id for the updated playlist

202

"""

203

204

def user_playlist_add_tracks(self, user, playlist_id, tracks, position=None):

205

"""

206

Add tracks to user playlist (legacy method, use playlist_add_items instead).

207

208

Requires scope: playlist-modify-public or playlist-modify-private

209

210

Args:

211

user (str): Spotify user ID (ignored in current API)

212

playlist_id (str): Spotify playlist ID or URI

213

tracks (list): List of track URIs to add (max 100)

214

position (int, optional): Position to insert tracks (default: end)

215

216

Returns:

217

dict: Object with snapshot_id for the updated playlist

218

"""

219

220

def user_playlist_add_episodes(self, user, playlist_id, episodes, position=None):

221

"""

222

Add episodes to user playlist (legacy method, use playlist_add_items instead).

223

224

Requires scope: playlist-modify-public or playlist-modify-private

225

226

Args:

227

user (str): Spotify user ID (ignored in current API)

228

playlist_id (str): Spotify playlist ID or URI

229

episodes (list): List of episode URIs to add (max 100)

230

position (int, optional): Position to insert episodes (default: end)

231

232

Returns:

233

dict: Object with snapshot_id for the updated playlist

234

"""

235

```

236

237

### Replacing and Reordering Items

238

239

Replace playlist contents and reorder items.

240

241

```python { .api }

242

def playlist_replace_items(self, playlist_id, items):

243

"""

244

Replace all items in playlist.

245

246

Requires scope: playlist-modify-public or playlist-modify-private

247

248

Args:

249

playlist_id (str): Spotify playlist ID or URI

250

items (list): List of track/episode URIs to replace with (max 100)

251

252

Returns:

253

dict: Object with snapshot_id for the updated playlist

254

"""

255

256

def user_playlist_replace_tracks(self, user, playlist_id, tracks):

257

"""

258

Replace all tracks in user playlist (legacy method, use playlist_replace_items instead).

259

260

Requires scope: playlist-modify-public or playlist-modify-private

261

262

Args:

263

user (str): Spotify user ID (ignored in current API)

264

playlist_id (str): Spotify playlist ID or URI

265

tracks (list): List of track URIs to replace with (max 100)

266

267

Returns:

268

dict: Object with snapshot_id for the updated playlist

269

"""

270

271

def playlist_reorder_items(self, playlist_id, range_start, insert_before,

272

range_length=1, snapshot_id=None):

273

"""

274

Reorder items in playlist.

275

276

Requires scope: playlist-modify-public or playlist-modify-private

277

278

Args:

279

playlist_id (str): Spotify playlist ID or URI

280

range_start (int): Position of first item to move

281

insert_before (int): Position to insert the items

282

range_length (int): Number of items to move (default: 1)

283

snapshot_id (str, optional): Playlist snapshot ID for consistency

284

285

Returns:

286

dict: Object with snapshot_id for the updated playlist

287

"""

288

289

def user_playlist_reorder_tracks(self, user, playlist_id, range_start, insert_before,

290

range_length=1, snapshot_id=None):

291

"""

292

Reorder tracks in user playlist (legacy method, use playlist_reorder_items instead).

293

294

Requires scope: playlist-modify-public or playlist-modify-private

295

296

Args:

297

user (str): Spotify user ID (ignored in current API)

298

playlist_id (str): Spotify playlist ID or URI

299

range_start (int): Position of first track to move

300

insert_before (int): Position to insert the tracks

301

range_length (int): Number of tracks to move (default: 1)

302

snapshot_id (str, optional): Playlist snapshot ID for consistency

303

304

Returns:

305

dict: Object with snapshot_id for the updated playlist

306

"""

307

```

308

309

### Removing Items from Playlists

310

311

Remove tracks and episodes from playlists.

312

313

```python { .api }

314

def playlist_remove_all_occurrences_of_items(self, playlist_id, items, snapshot_id=None):

315

"""

316

Remove all occurrences of items from playlist.

317

318

Requires scope: playlist-modify-public or playlist-modify-private

319

320

Args:

321

playlist_id (str): Spotify playlist ID or URI

322

items (list): List of track/episode URIs to remove (max 100)

323

snapshot_id (str, optional): Playlist snapshot ID for consistency

324

325

Returns:

326

dict: Object with snapshot_id for the updated playlist

327

"""

328

329

def playlist_remove_specific_occurrences_of_items(self, playlist_id, items, snapshot_id=None):

330

"""

331

Remove specific occurrences of items from playlist.

332

333

Requires scope: playlist-modify-public or playlist-modify-private

334

335

Args:

336

playlist_id (str): Spotify playlist ID or URI

337

items (list): List of objects with 'uri' and 'positions' keys (max 100)

338

snapshot_id (str, optional): Playlist snapshot ID for consistency

339

340

Returns:

341

dict: Object with snapshot_id for the updated playlist

342

"""

343

344

def user_playlist_remove_all_occurrences_of_tracks(self, user, playlist_id, tracks, snapshot_id=None):

345

"""

346

Remove all occurrences of tracks from user playlist (legacy method).

347

348

Requires scope: playlist-modify-public or playlist-modify-private

349

350

Args:

351

user (str): Spotify user ID (ignored in current API)

352

playlist_id (str): Spotify playlist ID or URI

353

tracks (list): List of track URIs to remove (max 100)

354

snapshot_id (str, optional): Playlist snapshot ID for consistency

355

356

Returns:

357

dict: Object with snapshot_id for the updated playlist

358

"""

359

360

def user_playlist_remove_specific_occurrences_of_tracks(self, user, playlist_id, tracks,

361

positions, snapshot_id=None):

362

"""

363

Remove specific occurrences of tracks from user playlist (legacy method).

364

365

Requires scope: playlist-modify-public or playlist-modify-private

366

367

Args:

368

user (str): Spotify user ID (ignored in current API)

369

playlist_id (str): Spotify playlist ID or URI

370

tracks (list): List of track URIs to remove

371

positions (list): List of positions for each track URI

372

snapshot_id (str, optional): Playlist snapshot ID for consistency

373

374

Returns:

375

dict: Object with snapshot_id for the updated playlist

376

"""

377

```

378

379

### Following Playlists

380

381

Follow and unfollow playlists, check following status.

382

383

```python { .api }

384

def current_user_follow_playlist(self, playlist_id, public=True):

385

"""

386

Follow playlist.

387

388

Requires scope: playlist-modify-public or playlist-modify-private

389

390

Args:

391

playlist_id (str): Spotify playlist ID or URI

392

public (bool): Show as public in user's profile (default: True)

393

394

Returns:

395

None

396

"""

397

398

def current_user_unfollow_playlist(self, playlist_id):

399

"""

400

Unfollow playlist.

401

402

Requires scope: playlist-modify-public or playlist-modify-private

403

404

Args:

405

playlist_id (str): Spotify playlist ID or URI

406

407

Returns:

408

None

409

"""

410

411

def playlist_is_following(self, playlist_id, user_ids):

412

"""

413

Check if users follow playlist.

414

415

Args:

416

playlist_id (str): Spotify playlist ID or URI

417

user_ids (list): List of user IDs to check (max 5)

418

419

Returns:

420

list: Boolean list indicating which users follow the playlist

421

"""

422

423

def user_playlist_follow_playlist(self, playlist_owner_id, playlist_id):

424

"""

425

Follow playlist (legacy method, use current_user_follow_playlist instead).

426

427

Requires scope: playlist-modify-public or playlist-modify-private

428

429

Args:

430

playlist_owner_id (str): Playlist owner's user ID (ignored in current API)

431

playlist_id (str): Spotify playlist ID or URI

432

433

Returns:

434

None

435

"""

436

437

def user_playlist_unfollow(self, user, playlist_id):

438

"""

439

Unfollow playlist (legacy method, use current_user_unfollow_playlist instead).

440

441

Requires scope: playlist-modify-public or playlist-modify-private

442

443

Args:

444

user (str): User ID (ignored in current API)

445

playlist_id (str): Spotify playlist ID or URI

446

447

Returns:

448

None

449

"""

450

451

def user_playlist_is_following(self, playlist_owner_id, playlist_id, user_ids):

452

"""

453

Check if users follow playlist (legacy method, use playlist_is_following instead).

454

455

Args:

456

playlist_owner_id (str): Playlist owner's user ID (ignored in current API)

457

playlist_id (str): Spotify playlist ID or URI

458

user_ids (list): List of user IDs to check (max 5)

459

460

Returns:

461

list: Boolean list indicating which users follow the playlist

462

"""

463

```

464

465

### Playlist Cover Images

466

467

Manage playlist cover images.

468

469

```python { .api }

470

def playlist_cover_image(self, playlist_id):

471

"""

472

Get playlist cover image.

473

474

Args:

475

playlist_id (str): Spotify playlist ID or URI

476

477

Returns:

478

list: List of image objects with URL, height, and width

479

"""

480

481

def playlist_upload_cover_image(self, playlist_id, image_b64):

482

"""

483

Upload custom playlist cover image.

484

485

Requires scope: ugc-image-upload, playlist-modify-public or playlist-modify-private

486

487

Args:

488

playlist_id (str): Spotify playlist ID or URI

489

image_b64 (str): Base64 encoded JPEG image data (max 256KB)

490

491

Returns:

492

None

493

"""

494

```

495

496

## Usage Examples

497

498

### Creating and Managing Playlists

499

500

```python

501

import spotipy

502

from spotipy.oauth2 import SpotifyOAuth

503

504

scope = "playlist-modify-public playlist-modify-private"

505

sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))

506

507

# Get current user ID

508

user = sp.me()

509

user_id = user['id']

510

511

# Create a new playlist

512

playlist = sp.user_playlist_create(

513

user=user_id,

514

name="My Awesome Playlist",

515

description="Created with Spotipy",

516

public=True

517

)

518

519

print(f"Created playlist: {playlist['name']} (ID: {playlist['id']})")

520

521

# Add tracks to the playlist

522

track_uris = [

523

'spotify:track:4iV5W9uYEdYUVa79Axb7Rh', # Mr. Brightside

524

'spotify:track:0VjIjW4GlUAb6qAOLklx2J', # Bohemian Rhapsody

525

'spotify:track:1301WleyT98MSxVHPZCA6M' # Sweet Child O' Mine

526

]

527

528

result = sp.playlist_add_items(playlist['id'], track_uris)

529

print(f"Added {len(track_uris)} tracks. Snapshot ID: {result['snapshot_id']}")

530

531

# Update playlist details

532

sp.playlist_change_details(

533

playlist['id'],

534

name="My Updated Playlist",

535

description="Updated description with more details",

536

public=False # Make it private

537

)

538

print("Playlist details updated")

539

```

540

541

### Managing Playlist Content

542

543

```python

544

playlist_id = "37i9dQZF1DXcBWIGoYBM5M" # Example playlist ID

545

546

# Get playlist information

547

playlist_info = sp.playlist(playlist_id)

548

print(f"Playlist: {playlist_info['name']} by {playlist_info['owner']['display_name']}")

549

print(f"Tracks: {playlist_info['tracks']['total']}")

550

print(f"Followers: {playlist_info['followers']['total']}")

551

552

# Get all tracks from playlist

553

tracks = []

554

results = sp.playlist_items(playlist_id, limit=50)

555

tracks.extend(results['items'])

556

557

while results['next']:

558

results = sp.next(results)

559

tracks.extend(results['items'])

560

561

print(f"\\nAll {len(tracks)} tracks:")

562

for i, item in enumerate(tracks[:10], 1): # Show first 10

563

track = item['track']

564

if track: # Check if track is not None (could be deleted)

565

artist_names = ', '.join([artist['name'] for artist in track['artists']])

566

print(f" {i}. {track['name']} - {artist_names}")

567

print(f" Added by: {item['added_by']['id']} on {item['added_at'][:10]}")

568

```

569

570

### Playlist Collaboration

571

572

```python

573

# Create a collaborative playlist

574

collaborative_playlist = sp.user_playlist_create(

575

user=user_id,

576

name="Team Collaborative Playlist",

577

description="Add your favorite tracks!",

578

collaborative=True,

579

public=False # Private but collaborative

580

)

581

582

print(f"Created collaborative playlist: {collaborative_playlist['external_urls']['spotify']}")

583

584

# Check who's following a playlist

585

user_ids_to_check = ['spotify', 'example_user', user_id]

586

following_status = sp.playlist_is_following(collaborative_playlist['id'], user_ids_to_check)

587

588

for user_id_check, is_following in zip(user_ids_to_check, following_status):

589

status = "following" if is_following else "not following"

590

print(f"User {user_id_check} is {status} the playlist")

591

```

592

593

### Advanced Playlist Operations

594

595

```python

596

# Reorder tracks in playlist

597

my_playlist_id = "your_playlist_id_here"

598

599

# Move track at position 0 to position 5

600

result = sp.playlist_reorder_items(

601

playlist_id=my_playlist_id,

602

range_start=0, # Move track at position 0

603

insert_before=6, # Insert before position 6 (so it ends up at position 5)

604

range_length=1 # Move 1 track

605

)

606

print(f"Reordered playlist. New snapshot: {result['snapshot_id']}")

607

608

# Remove specific occurrences of tracks

609

tracks_to_remove = [

610

{

611

"uri": "spotify:track:4iV5W9uYEdYUVa79Axb7Rh",

612

"positions": [0, 3] # Remove from positions 0 and 3

613

}

614

]

615

616

result = sp.playlist_remove_specific_occurrences_of_items(

617

my_playlist_id,

618

tracks_to_remove

619

)

620

print(f"Removed specific track occurrences. New snapshot: {result['snapshot_id']}")

621

622

# Replace entire playlist content

623

new_track_uris = [

624

'spotify:track:0VjIjW4GlUAOLklx2J',

625

'spotify:track:1301WleyT98MSxVHPZCA6M',

626

'spotify:track:4VqPOruhp5EdPBeR92t6lQ'

627

]

628

629

result = sp.playlist_replace_items(my_playlist_id, new_track_uris)

630

print(f"Replaced all playlist content. New snapshot: {result['snapshot_id']}")

631

```

632

633

### Working with Playlist Images

634

635

```python

636

import base64

637

638

# Get current playlist cover

639

cover_images = sp.playlist_cover_image(playlist_id)

640

if cover_images:

641

print(f"Current cover image: {cover_images[0]['url']}")

642

print(f"Dimensions: {cover_images[0]['width']}x{cover_images[0]['height']}")

643

644

# Upload custom cover image

645

# Note: Image must be JPEG format, base64 encoded, max 256KB

646

with open("my_playlist_cover.jpg", "rb") as image_file:

647

image_b64 = base64.b64encode(image_file.read()).decode('utf-8')

648

649

try:

650

sp.playlist_upload_cover_image(playlist_id, image_b64)

651

print("Successfully uploaded custom playlist cover!")

652

except Exception as e:

653

print(f"Failed to upload cover: {e}")

654

```

655

656

### Bulk Playlist Operations

657

658

```python

659

# Get all user's playlists

660

all_playlists = []

661

results = sp.current_user_playlists(limit=50)

662

all_playlists.extend(results['items'])

663

664

while results['next']:

665

results = sp.next(results)

666

all_playlists.extend(results['items'])

667

668

print(f"Found {len(all_playlists)} playlists")

669

670

# Analyze playlists

671

total_tracks = 0

672

collaborative_count = 0

673

public_count = 0

674

675

for playlist in all_playlists:

676

total_tracks += playlist['tracks']['total']

677

if playlist['collaborative']:

678

collaborative_count += 1

679

if playlist['public']:

680

public_count += 1

681

682

print(f"Total tracks across all playlists: {total_tracks}")

683

print(f"Collaborative playlists: {collaborative_count}")

684

print(f"Public playlists: {public_count}")

685

print(f"Private playlists: {len(all_playlists) - public_count}")

686

687

# Find largest playlists

688

largest_playlists = sorted(all_playlists, key=lambda x: x['tracks']['total'], reverse=True)[:5]

689

print("\\nLargest playlists:")

690

for playlist in largest_playlists:

691

print(f" {playlist['name']}: {playlist['tracks']['total']} tracks")

692

```

693

694

## Required Scopes Summary

695

696

- **playlist-read-private**: Read user's private playlists

697

- **playlist-read-collaborative**: Read user's collaborative playlists

698

- **playlist-modify-public**: Create and modify user's public playlists

699

- **playlist-modify-private**: Create and modify user's private playlists

700

- **ugc-image-upload**: Upload custom playlist cover images