diff --git a/man/lkt.template b/man/lkt.template
index 7c89fdd665d397666f747c185578b8a84ae09a65..bf6c2c3efc710367c5885b6f735735972a26febc 100644
--- a/man/lkt.template
+++ b/man/lkt.template
@@ -119,6 +119,13 @@ playing one
 .TP
 \fBqueue replace\fP <plt-name>
 Replace the queue with the content of a playlist. Keep the playling state
+.TP
+\fBqueue swap\fP <pos1> <pos2>
+Swaps two karas in the queue by their position.
+.TP
+\fBqueue swapid\fP <id1> <id2>
+Swaps two karas in the queue by their id. Note that if there are two of the
+same kara in the queue, the selected one is not define.
 .PP
 
 \fISEARCH-COMMANDS\fP
diff --git a/src/main/lkt.c b/src/main/lkt.c
index 67cf1a8b51388d2b1c16f62834519e00be188dfe..3a0bde57144e90bfb00db7ffc409a2b75a3bed79 100644
--- a/src/main/lkt.c
+++ b/src/main/lkt.c
@@ -284,6 +284,19 @@ send_cmd_with_uri(FILE *sock, char *cmd, int argc, const char **argv)
 
 /* Functions implementing options. */
 
+#define just_send_two_args(func, cmd)               \
+noreturn void func (struct cmd_args *args) {        \
+    fail_if(args->argc != 2, "Need two arguments"); \
+    FILE *sock = lkt_connect();                     \
+    char buff[2];                                   \
+    write_socket(sock, cmd " %s %s\n",              \
+                 args->argv[0], args->argv[1]);     \
+    exit_with_status(sock, buff);                   \
+}
+just_send_two_args(queue_swap__,   "swap")
+just_send_two_args(queue_swapid__, "swapid")
+#undef just_send_two_args
+
 #define just_send_one_arg(func, cmd)                \
 noreturn void func (struct cmd_args *args) {        \
     fail_if(args->argc != 1, "Invalid argument");   \
@@ -589,7 +602,7 @@ noreturn void
 queue_pop__(struct cmd_args *args)
 {
     fail_if(args->argc, "Invalid argument");
-    int songid = 0;
+    int song = 0;
     char buff[LKT_MESSAGE_MAX];
     FILE *sock = lkt_connect();
 
@@ -601,7 +614,7 @@ queue_pop__(struct cmd_args *args)
         memset(buff, 0, LKT_MESSAGE_MAX * sizeof(char));
         read_socket(sock, buff, LKT_MESSAGE_MAX - 1);
         size_t len = strcspn(buff, LKT_KEY_VALUE_SEP);
-        assign_int("songid", songid)
+        assign_int("song", song)
 
         /* At this point every key has been parsed. */
         if (STR_NMATCH(buff, "OK", 2))
@@ -610,20 +623,20 @@ queue_pop__(struct cmd_args *args)
             exit(EXIT_FAILURE);
     }
 #undef assign_int
+    song += 1; /* Needs the +1, see status command */
 
     fclose(sock);
     sock = lkt_connect();
-    if (!songid)
+    if (!song)
         exit(EXIT_FAILURE);
-    write_socket(sock, "next\ndeleteid %d\n", songid);
+    write_socket(sock, "next\ndelete %d\n", song);
     exit_with_status(sock, buff);
 }
 
 noreturn void
 status__(struct cmd_args *args)
 {
-    if (args->argc != 0)
-        fail("Invalid argument, the status command takes no arguments");
+    fail_if(args->argc != 0, "Invalid argument, the status command takes no arguments");
 
     static const char *const status_str__ = "status\n";
     static const char *const stats_str__  = "stats\n";
@@ -1150,6 +1163,8 @@ static struct cmd_opt options_queue[] = {
     { .name = "dump",       .call = queue_dump__    },
     { .name = "id",         .call = queue_id__      },
     { .name = "flatten",    .call = queue_flatten__ },
+    { .name = "swap",       .call = queue_swap__    },
+    { .name = "swapid",     .call = queue_swapid__  },
     CMD_OPT_DEFAULT(queue_list__),
 };