Skip to content

OwnTone smart playlists

To add a smart playlist to the server, create a new text file with a filename ending with .smartpl; the filename doesn't matter, only the .smartpl ending does. The file must be placed somewhere in your library folder.


The contents of a smart playlist must follow the syntax:

"Playlist Name" { expression }

There is exactly one smart playlist allowed for a .smartpl file.

An expression consists of:

field-name operator operand

Where valid field-names (with their types) are:

  • artist (string)
  • album_artist (string)
  • album (string)
  • title (string)
  • genre (string)
  • composer (string)
  • comment (string)
  • path (string)
  • type (string)
  • grouping (string)
  • data_kind (enumeration)
  • media_kind (enumeration)
  • play_count (integer)
  • skip_count (integer)
  • rating (integer)
  • year (integer)
  • compilation (integer)
  • track (integer)
  • disc (integer)
  • time_added (date)
  • time_modified (date)
  • time_played (date)
  • time_skipped (date)
  • random (special)
  • file_size (integer)

Valid operators include:

  • is, includes, starts with, ends with (string)
  • >, <, <=, >=, = (int)
  • after, before (date)
  • is (enumeration)

The is operator must exactly match the field value, while the includes operator matches a substring. The starts with operator matches, if the value starts with the given prefix, and ends with matches the opposite. All these matches are case-insensitive.

Valid operands include:

  • "string value" (string)
  • integer (int)

Valid operands for the enumeration data_kind are:

  • file
  • url
  • spotify
  • pipe

Valid operands for the enumeration media_kind are:

  • music
  • movie
  • podcast
  • audiobook
  • tvshow

Multiple expressions can be anded or ored together, using the keywords OR and AND. The unary not operator is also supported using the keyword NOT.

It is possible to define the sort order and limit the number of items by adding an order clause and/or a limit clause after the last expression:

"Playlist Name" { expression ORDER BY field-name sort-direction LIMIT limit }

"sort-direction" is either ASC (ascending) or DESC (descending). "limit" is the maximum number of items.

There is additionally a special random field-name that can be used in conjunction with limit to select a random number of items based on current expression.


"techno" {
   genre includes "techno"
   and artist includes "zombie"

This would match songs by "Rob Zombie" or "White Zombie", as well as those with a genre of "Techno-Industrial" or "Trance/Techno", for example.

"techno 2015" {
   genre includes "techno"
   and artist includes "zombie"
   and not genre includes "industrial"

This would exclude e. g. songs with the genre "Techno-Industrial".

"Local music" {
  data_kind is file
  and media_kind is music

This would match all songs added as files to the library that are not placed under the folders for podcasts, audiobooks.

"Unplayed podcasts and audiobooks" {
  play_count = 0
  and (media_kind is podcast or media_kind is audiobook)

This would match any podcast and audiobook file that was never played.

"Recently added music" {
  media_kind is music
  order by time_added desc
  limit 10
This would match the last 10 music files added to the library.

"Random 10 Rated Pop songs" {
  rating > 0 and
  genre is "Pop" and
  media_kind is music
  order by random desc
  limit 10
This generates a random set of, maximum of 10, rated Pop music tracks every time the playlist is queried.

Date operand syntax

One example of a valid date is a date in yyyy-mm-dd format:

"Files added after January 1, 2004" {
  time_added after 2004-01-01

There are also some special date keywords:

  • today, yesterday, this week, last week, last month, last year

These dates refer to the start of that period; today means 00:00hrs of today, this week means current Monday 00:00hrs, last week means the previous Monday 00:00hrs, last month is the first day of the previous month at 00:00hrs etc.

A valid date can also be made by applying an interval to a date. Intervals can be defined as days, weeks, months, years. As an example, a valid date might be:

3 weeks before today or 3 weeks ago


"Recently Added" {
    time_added after 2 weeks ago

This matches all songs added in the last 2 weeks.

"Recently played audiobooks" {
    time_played after last week
    and media_kind is audiobook

This matches all audiobooks played since the start of the last Monday 00:00AM.

All dates, except for YYYY-DD-HH, are relative to the day of when the server evaluates the smartpl query; time_added after today run on a Monday would match against items added since Monday 00:00hrs and evaluating the same smartpl on Friday would only match against added on Friday 00:00hrs.

Note that time_added after 4 weeks ago and time_added after last month are subtly different; the former is exactly 4 weeks ago (from today) whereas the latter is the first day of the previous month.

Differences to mt-daapd smart playlists

The syntax is really close to the mt-daapd smart playlist syntax (see

Even this documentation is based on the file linked above.

Some differences are:

  • only one smart playlist per file
  • the not operator must be placed before an expression and not before the operator
  • ||, &&, ! are not supported (use or, and, not)
  • comments are not supported