diff --git a/api/funkwhale_api/subsonic/views.py b/api/funkwhale_api/subsonic/views.py
index 6633224dfbd68fc876895039d200b23652b0dcf8..60209a92d238ab762c3d5c9b524a3bd06b650185 100644
--- a/api/funkwhale_api/subsonic/views.py
+++ b/api/funkwhale_api/subsonic/views.py
@@ -1,3 +1,6 @@
+"""
+Documentation of Subsonic API can be found at http://www.subsonic.org/pages/api.jsp
+"""
 import datetime
 import functools
 
@@ -427,7 +430,34 @@ class SubsonicViewSet(viewsets.GenericViewSet):
                 Q(tagged_items__tag__name=genre)
                 | Q(artist__tagged_items__tag__name=genre)
             )
+        elif type == "byYear":
+            try:
+                boundaries = [
+                    int(data.get("fromYear", 0)),
+                    int(data.get("toYear", 99999999)),
+                ]
 
+            except (TypeError, ValueError):
+                return response.Response(
+                    {
+                        "error": {
+                            "code": 10,
+                            "message": "Invalid fromYear or toYear parameter",
+                        }
+                    }
+                )
+            # because, yeah, the specification explicitly state that fromYear can be greater
+            # than toYear, to indicate reverse ordering…
+            # http://www.subsonic.org/pages/api.jsp#getAlbumList2
+            from_year = min(boundaries)
+            to_year = max(boundaries)
+            queryset = queryset.filter(
+                release_date__year__gte=from_year, release_date__year__lte=to_year
+            )
+            if boundaries[0] <= boundaries[1]:
+                queryset = queryset.order_by("release_date")
+            else:
+                queryset = queryset.order_by("-release_date")
         try:
             offset = int(data["offset"])
         except (TypeError, KeyError, ValueError):
diff --git a/api/tests/subsonic/test_views.py b/api/tests/subsonic/test_views.py
index 298ad34f7281ffe5148af6427dd35eb02dcfbe2b..d58cc3932c61a4763db228716e7a418f417a3432 100644
--- a/api/tests/subsonic/test_views.py
+++ b/api/tests/subsonic/test_views.py
@@ -469,6 +469,35 @@ def test_get_album_list2_by_genre(f, db, logged_in_api_client, factories):
     }
 
 
+@pytest.mark.parametrize(
+    "params, expected",
+    [
+        ({"type": "byYear", "fromYear": 1902, "toYear": 1903}, [2, 3]),
+        # Because why not, it's supported in Subsonic API…
+        # http://www.subsonic.org/pages/api.jsp#getAlbumList2
+        ({"type": "byYear", "fromYear": 1903, "toYear": 1902}, [3, 2]),
+    ],
+)
+def test_get_album_list2_by_year(params, expected, db, logged_in_api_client, factories):
+    albums = [
+        factories["music.Album"](
+            playable=True, release_date=datetime.date(1900 + i, 1, 1)
+        )
+        for i in range(5)
+    ]
+    url = reverse("api:subsonic-get_album_list2")
+    base_params = {"f": "json"}
+    base_params.update(params)
+    response = logged_in_api_client.get(url, base_params)
+
+    assert response.status_code == 200
+    assert response.data == {
+        "albumList2": {
+            "album": serializers.get_album_list2_data([albums[i] for i in expected])
+        }
+    }
+
+
 @pytest.mark.parametrize("f", ["json"])
 @pytest.mark.parametrize(
     "tags_field",
diff --git a/changes/changelog.d/934.doc b/changes/changelog.d/934.doc
new file mode 100644
index 0000000000000000000000000000000000000000..4b319c92214cbc20e4fedaed7be5f8b4b3f9325e
--- /dev/null
+++ b/changes/changelog.d/934.doc
@@ -0,0 +1 @@
+Documented how to create DB extension by hand in case of permission error during migrations (#934)
diff --git a/changes/changelog.d/936.enhancement b/changes/changelog.d/936.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..2c16ffe542f9b83a35da18f429d66bc04a9f8937
--- /dev/null
+++ b/changes/changelog.d/936.enhancement
@@ -0,0 +1 @@
+Support byYear filtering in Subsonic API (#936)
diff --git a/docs/admin/upgrading.rst b/docs/admin/upgrading.rst
index d18dd74475300a66201050c8f9afd59d17147c04..9f0dc37746273312912d55fccb86aeebec4a1f3b 100644
--- a/docs/admin/upgrading.rst
+++ b/docs/admin/upgrading.rst
@@ -192,6 +192,12 @@ match what is described in :doc:`/installation/debian`:
     # restart the services
     sudo systemctl start funkwhale.target
 
+.. note::
+    If you see a PermissionError when running the ``migrate`` command, try running the following commands by hand, and relaunch the migrations::
+
+        sudo -u postgres psql funkwhale -c 'CREATE EXTENSION IF NOT EXISTS "citext";'
+        sudo -u postgres psql funkwhale -c 'CREATE EXTENSION IF NOT EXISTS "unaccent";'
+
 .. warning::
 
     You may sometimes get the following warning while applying migrations::
diff --git a/docs/installation/external_dependencies.rst b/docs/installation/external_dependencies.rst
index 1e108f00a56543d497e7d8059c6f87e8b7220dc8..6925eaf729f11cc7d0561fe0f2e2ba6ff4d8e2d3 100644
--- a/docs/installation/external_dependencies.rst
+++ b/docs/installation/external_dependencies.rst
@@ -66,6 +66,7 @@ for Funkwhale to work properly:
 .. code-block:: shell
 
     sudo -u postgres psql funkwhale -c 'CREATE EXTENSION "unaccent";'
+    sudo -u postgres psql funkwhale -c 'CREATE EXTENSION "citext";'
 
 
 Cache setup (Redis)