diff --git a/src/rust/kurisu_api/src/v1.rs b/src/rust/kurisu_api/src/v1.rs
index 6cd25131ca7b49a4b2d692fef2a70672926f9602..31af93179b6c66abaacd506c37fec28ddc6bee1e 100644
--- a/src/rust/kurisu_api/src/v1.rs
+++ b/src/rust/kurisu_api/src/v1.rs
@@ -1,9 +1,6 @@
 //! Object rules for the Kurisu's V1 API
 
-use commons::either;
-use serde::Deserialize;
-
-use crate::new_route;
+use crate::*;
 
 #[derive(Debug, Deserialize, Clone, Copy)]
 pub struct Kara<'a> {
@@ -60,6 +57,15 @@ where
                 write!(formatter, "a kara or a sequence of karas")
             }
 
+            fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
+            where
+                A: serde::de::MapAccess<'de>,
+            {
+                let deserializer = serde::de::value::MapAccessDeserializer::new(map);
+                let kara: Kara<'de> = Deserialize::deserialize(deserializer)?;
+                Ok(MaybeKaraList::Single(kara))
+            }
+
             fn visit_seq<S>(self, mut visitor: S) -> Result<Self::Value, S::Error>
             where
                 S: serde::de::SeqAccess<'de>,
@@ -92,3 +98,69 @@ pub struct KaraDl<'a> {
 new_route! { GetKara      :: "/@" #1          -> MaybeKaraList }
 new_route! { GetKaraPerId :: "/id/@" #1       -> Kara          }
 new_route! { GetKaraDl    :: "/download/@" #1 -> KaraDl        }
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use commons::assert_ok;
+
+    #[test]
+    fn maybe_multi_kara() {
+        let karas = assert_ok!(serde_json::from_str::<MaybeKaraList>("[]"));
+        assert!(matches!(karas, MaybeKaraList::Empty));
+
+        let karas = assert_ok!(serde_json::from_str::<MaybeKaraList>(
+            r#"{ "id": 1
+               , "source_name": "Totoro"
+               , "song_name": "Totoro"
+               , "song_type": "Totoro"
+               , "song_number": 1
+               , "category": "vo"
+               , "language": "fr"
+               , "author_name": "Totoro"
+               , "author_year": "Some valide date"
+               , "is_new": 1
+               , "upload_comment": ""
+               , "popularity": 42
+               , "unix_timestamp": 2077
+               , "size": 69
+            }"#
+        ));
+        assert!(matches!(karas, MaybeKaraList::Single(_)));
+
+        let karas = assert_ok!(serde_json::from_str::<MaybeKaraList>(
+            r#"[ { "id": 1
+                 , "source_name": "Totoro"
+                 , "song_name": "Totoro"
+                 , "song_type": "Totoro"
+                 , "song_number": 1
+                 , "category": "vo"
+                 , "language": "fr"
+                 , "author_name": "Totoro"
+                 , "author_year": "Some valide date"
+                 , "is_new": 1
+                 , "upload_comment": ""
+                 , "popularity": 42
+                 , "unix_timestamp": 2077
+                 , "size": 69
+                 },
+                 { "id": 1
+                 , "source_name": "Totoro"
+                 , "song_name": "Totoro"
+                 , "song_type": "Totoro"
+                 , "song_number": 1
+                 , "category": "vo"
+                 , "language": "fr"
+                 , "author_name": "Totoro"
+                 , "author_year": "Some valide date"
+                 , "is_new": 1
+                 , "upload_comment": ""
+                 , "popularity": 42
+                 , "unix_timestamp": 2077
+                 , "size": 69
+                 }
+            ]"#
+        ));
+        assert!(matches!(karas, MaybeKaraList::Multi(vec) if vec.len() == 2));
+    }
+}