diff --git a/api/funkwhale_api/music/filters.py b/api/funkwhale_api/music/filters.py
index 7f09924d1026bb0ff4eb167247ffa934bd61cd6f..feebaa5421e98e60a8c95e6f451002dde197c1d9 100644
--- a/api/funkwhale_api/music/filters.py
+++ b/api/funkwhale_api/music/filters.py
@@ -9,6 +9,7 @@ from funkwhale_api.common import fields
 from funkwhale_api.common import filters as common_filters
 from funkwhale_api.common import search
 from funkwhale_api.moderation import filters as moderation_filters
+from funkwhale_api.tags import filters as tags_filters
 
 from . import models
 from . import utils
@@ -24,6 +25,28 @@ def filter_tags(queryset, name, value):
 TAG_FILTER = common_filters.MultipleQueryFilter(method=filter_tags)
 
 
+class RelatedFilterSet(filters.FilterSet):
+    related_type = int
+    related_field = "pk"
+    related = filters.CharFilter(field_name="_", method="filter_related")
+
+    def filter_related(self, queryset, name, value):
+        if not value:
+            return queryset.none()
+        try:
+            pk = self.related_type(value)
+        except (TypeError, ValueError):
+            return queryset.none()
+
+        try:
+            obj = queryset.model.objects.get(**{self.related_field: pk})
+        except queryset.model.DoesNotExist:
+            return queryset.none()
+
+        queryset = queryset.exclude(pk=obj.pk)
+        return tags_filters.get_by_similar_tags(queryset, obj.get_tags())
+
+
 class ChannelFilterSet(filters.FilterSet):
 
     channel = filters.CharFilter(field_name="_", method="filter_channel")
@@ -70,6 +93,7 @@ class LibraryFilterSet(filters.FilterSet):
 
 
 class ArtistFilter(
+    RelatedFilterSet,
     LibraryFilterSet,
     audio_filters.IncludeChannelsFilterSet,
     moderation_filters.HiddenContentFilterSet,
@@ -88,6 +112,7 @@ class ArtistFilter(
             ("creation_date", "creation_date"),
             ("modification_date", "modification_date"),
             ("?", "random"),
+            ("tag_matches", "related"),
         )
     )
 
@@ -109,6 +134,7 @@ class ArtistFilter(
 
 
 class TrackFilter(
+    RelatedFilterSet,
     ChannelFilterSet,
     LibraryFilterSet,
     audio_filters.IncludeChannelsFilterSet,
@@ -140,6 +166,7 @@ class TrackFilter(
             ("artist__name", "artist__name"),
             ("artist__modification_date", "artist__modification_date"),
             ("?", "random"),
+            ("tag_matches", "related"),
         )
     )
 
@@ -217,6 +244,7 @@ class UploadFilter(audio_filters.IncludeChannelsFilterSet):
 
 
 class AlbumFilter(
+    RelatedFilterSet,
     ChannelFilterSet,
     LibraryFilterSet,
     audio_filters.IncludeChannelsFilterSet,
@@ -239,6 +267,7 @@ class AlbumFilter(
             ("title", "title"),
             ("artist__modification_date", "artist__modification_date"),
             ("?", "random"),
+            ("tag_matches", "related"),
         )
     )
 
diff --git a/api/funkwhale_api/tags/filters.py b/api/funkwhale_api/tags/filters.py
index e0ac9675ab7511f043195aaea83b31a1e9fe462b..c41ace91b385cab033a31a09269a649b93d3984c 100644
--- a/api/funkwhale_api/tags/filters.py
+++ b/api/funkwhale_api/tags/filters.py
@@ -1,3 +1,5 @@
+from django.db import models as dj_models
+
 import django_filters
 from django_filters import rest_framework as filters
 
@@ -19,3 +21,19 @@ class TagFilter(filters.FilterSet):
     class Meta:
         model = models.Tag
         fields = {"q": ["exact"], "name": ["exact", "startswith"]}
+
+
+def get_by_similar_tags(qs, tags):
+    """
+    Return a queryset of obects with at least one matching tag.
+    Annotate the queryset so you can order later by number of matches.
+    """
+    qs = qs.filter(tagged_items__tag__name__in=tags).annotate(
+        tag_matches=dj_models.Count(
+            dj_models.Case(
+                dj_models.When(tagged_items__tag__name__in=tags, then=1),
+                output_field=dj_models.IntegerField(),
+            )
+        )
+    )
+    return qs.distinct()
diff --git a/api/tests/music/test_filters.py b/api/tests/music/test_filters.py
index 87d8c4816d34c1b681fafc10c554733bfc3c16c3..f078932a89abefda1730194bf41c514f8110a75f 100644
--- a/api/tests/music/test_filters.py
+++ b/api/tests/music/test_filters.py
@@ -203,3 +203,41 @@ def test_track_filter_artist_includes_album_artist(
     )
 
     assert filterset.qs == [track2, track1]
+
+
+@pytest.mark.parametrize(
+    "factory_name, filterset_class",
+    [
+        ("music.Track", filters.TrackFilter),
+        ("music.Artist", filters.ArtistFilter),
+        ("music.Album", filters.AlbumFilter),
+    ],
+)
+def test_filter_tag_related(
+    factory_name,
+    filterset_class,
+    factories,
+    anonymous_user,
+    queryset_equal_list,
+    mocker,
+):
+    factories["tags.Tag"](name="foo")
+    factories["tags.Tag"](name="bar")
+    factories["tags.Tag"](name="baz")
+    factories["tags.Tag"]()
+    factories["tags.Tag"]()
+
+    matches = [
+        factories[factory_name](set_tags=["foo", "bar", "baz", "noop"]),
+        factories[factory_name](set_tags=["foo", "baz", "noop"]),
+        factories[factory_name](set_tags=["baz", "noop"]),
+    ]
+    factories[factory_name](set_tags=["noop"]),
+    obj = factories[factory_name](set_tags=["foo", "bar", "baz"])
+
+    filterset = filterset_class(
+        {"related": obj.pk, "ordering": "-related"},
+        request=mocker.Mock(user=anonymous_user, actor=None),
+        queryset=obj.__class__.objects.all(),
+    )
+    assert filterset.qs == matches
diff --git a/changes/changelog.d/1145.enhancement b/changes/changelog.d/1145.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..eefc8d46de74912585d5ca8e2dd7b4768ee85f80
--- /dev/null
+++ b/changes/changelog.d/1145.enhancement
@@ -0,0 +1 @@
+Support ordering=random for artists, albums, tracks and channels endpoints (#1145)
diff --git a/changes/changelog.d/api-related.enhancement b/changes/changelog.d/api-related.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..82be1c0f0c7ded24d2d06eff0640dda4012a355f
--- /dev/null
+++ b/changes/changelog.d/api-related.enhancement
@@ -0,0 +1 @@
+Added a new ?related=obj_id filter for artists, albums and tracks, based on tags