diff --git a/CHANGELOG.md b/CHANGELOG.md
index 405f9f40e75fdbc403c9be3e59386120f6a994a6..d6774a620e6cb763c7aba1a9f1e8f4e9f4a2dd2b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,8 +12,9 @@
 - Add SDL2-Image lib to the dependencies (--with-depends)
 - Add klkt autolaunch option to config file
 - Add the \_\_flat command to set all priorities to 1 in the queue
+- Add MPD commands: seek, seekid, seekcur, delete (partial), playlistid
+- Alias list\* commands as find
 - Remove archlinux package support (replaced by AppImage)
-- Add MPD commands: seek, seekid, seekcur, delete (partial)
 - Fix dl process with the repo module
 - Fix: the moveid was in fact a move command, no range supported
 - Bug fix: reduce libs to link to lkt (dear autoconf...)
diff --git a/README.md b/README.md
index 4b0fa9998ce54637181931aeb5a5b809cddc68bf..915d9f5e7a1741a2994179951758b537b15ff164 100644
--- a/README.md
+++ b/README.md
@@ -217,7 +217,7 @@ For the compatibility column, the possible values are the following:
 | `moveid {from} {to}`                      | `moveid {from} {to}`                  | ~     | `to` is always an absolute position               |
 | `playlist`                                | `playlist`                            | +     |                                                   |
 | `playlistfind {tag} {needle}`             | `playlistfind {uri}`                  | ~     | uses lektord URIs                                 |
-| `playlistid {songid}`                     |                                       | TODO  | not implemented                                   |
+| `playlistid {songid}`                     | `playlistid {id}                      | ~     | the uri is only an id                             |
 | `playlistinfo [[songpos]/[start:end]]`    | `playlistinfo`                        | -     | is an alias to `playlist`                         |
 | `playlistsearch {taf} {needle}`           | `playlistsearch {uri}`                | ~     | uses lektord URIs                                 |
 | `plchanges {version} [start:end]`         |                                       |       | not implemented                                   |
diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h
index 8c1da8c23443ed97dd683f6f3644a621d8780f50..e5b45e4e2d9d576fd0b19dfd3e3555f64d84e092 100644
--- a/inc/lektor/commands.h
+++ b/inc/lektor/commands.h
@@ -46,7 +46,8 @@ bool command_dump   (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]);
 bool command_swap   (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]);
 bool command_flat   (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]);
 
-bool command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
+bool command_queue_list  (struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
+bool command_queue_listid(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX]);
 
 /* The playlists */
 bool command_plt_create(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]);
diff --git a/inc/lektor/database.h b/inc/lektor/database.h
index fa74abee07f0c89f94b8a0904e4718229e39041d..68b93cc5d84b098ecd0e07b0b157e9dba47d005e 100644
--- a/inc/lektor/database.h
+++ b/inc/lektor/database.h
@@ -87,6 +87,7 @@ struct lkt_callback {
 /* List the content of the queue */
 bool database_queue_list(volatile sqlite3 *db, size_t from, size_t to,
                          struct lkt_callback *callback);
+bool database_queue_probe_id(volatile sqlite3 *db, int id);
 
 /* Search the database */
 struct lkt_search {
diff --git a/src/base/commands.c b/src/base/commands.c
index 4b6d3aebc715704d7ab3107f619875478f180df0..0651f6b7ecd2cc409ae8d670d3f9283e37d74e95 100644
--- a/src/base/commands.c
+++ b/src/base/commands.c
@@ -959,6 +959,15 @@ command_shuffle(struct lkt_state *srv, char UNUSED *args[LKT_MESSAGE_ARGS_MAX])
     return true;
 }
 
+bool
+command_queue_listid(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX])
+{
+    RETURN_UNLESS(args && args[0], "Invalid arguments", false);
+    long id = strtol(args[0], NULL, 0);
+    return database_queue_probe_id(srv->db, id) &&
+           command_findid(srv, c, args[0]);
+}
+
 bool
 command_queue_list(struct lkt_state *srv, size_t c, char *args[LKT_MESSAGE_ARGS_MAX])
 {
diff --git a/src/database/queue.c b/src/database/queue.c
index 61bb64a1bc799cbeefa41e7cae21fe9affd78f90..dd0a4151b106c2627c2a3ebcfa978b223acab4e5 100644
--- a/src/database/queue.c
+++ b/src/database/queue.c
@@ -802,6 +802,21 @@ error:
     return false;
 }
 
+bool
+database_queue_probe_id(volatile sqlite3 *db, int id)
+{
+    bool sta               = false;
+    sqlite3_stmt *stmt     = NULL;
+    static const char *SQL = "SELECT * FROM queue WHERE kara_id = ?;";
+    SQLITE_PREPARE(db, stmt, SQL, error);
+    SQLITE_BIND_INT(db, stmt, 1, id, error);
+    SQLITE_STEP_ROW(db, stmt, error);
+    sta = true;
+error:
+    sqlite3_finalize(stmt);
+    return sta;
+}
+
 bool
 database_queue_shuffle(volatile sqlite3 *db)
 {
diff --git a/src/net/listen.c b/src/net/listen.c
index 2f3fcbf1ef5c12161b8fbcc5a54edd806ef4e4ec..a0ecab1b46318123b4c8a6f2b281a2a023983de0 100644
--- a/src/net/listen.c
+++ b/src/net/listen.c
@@ -217,6 +217,8 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd)
         else if (STR_MATCH(cmd.name, "seekcur"))
             err = ! command_seekcur(srv, cmd.args);
 
+        else if (STR_MATCH(cmd.name, "playlistid"))
+            err = ! command_queue_listid(srv, c, cmd.args);
         else if (STR_MATCH(cmd.name, "playlist") || STR_MATCH(cmd.name, "playlistinfo"))
             err = ! command_queue_list(srv, c, cmd.args);
         else if (STR_MATCH(cmd.name, "playlistfind") || STR_MATCH(cmd.name, "playlistsearch"))