diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index cf48667cc6eade81eddbc4ca2a8e8282a03b194c..5d8035f358f4dd9cdc3fbaebf6e7402f614f976e 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -22,6 +22,7 @@ from versatileimagefield.fields import VersatileImageField
 
 from funkwhale_api import downloader
 from funkwhale_api import musicbrainz
+from funkwhale_api.federation import utils as federation_utils
 from . import importers
 from . import utils
 
@@ -69,6 +70,12 @@ class APIModelMixin(models.Model):
                 pass
         return cleaned_data
 
+    @property
+    def musicbrainz_url(self):
+        if self.mbid:
+            return 'https://musicbrainz.org/{}/{}'.format(
+                self.musicbrainz_model, self.mbid)
+
 
 class Artist(APIModelMixin):
     name = models.CharField(max_length=255)
@@ -426,6 +433,11 @@ class TrackFile(models.Model):
         shutil.rmtree(tmp_dir)
         return self.audio_file
 
+    def get_federation_url(self):
+        return federation_utils.full_url(
+            '/federation/music/file/{}'.format(self.uuid)
+        )
+
     @property
     def path(self):
         if settings.PROTECT_AUDIO_FILES:
diff --git a/api/funkwhale_api/music/serializers.py b/api/funkwhale_api/music/serializers.py
index 9f0b7af5c2f27b63c3477b05cf53086f62c7f7c5..5cd2f2cc218c3b1df40adff881d63b0cb6a1f21f 100644
--- a/api/funkwhale_api/music/serializers.py
+++ b/api/funkwhale_api/music/serializers.py
@@ -3,6 +3,8 @@ from rest_framework import serializers
 from taggit.models import Tag
 
 from funkwhale_api.activity import serializers as activity_serializers
+from funkwhale_api.federation.serializers import AP_CONTEXT
+from funkwhale_api.federation import utils as federation_utils
 
 from . import models
 
@@ -212,6 +214,29 @@ class AudioSerializer(serializers.Serializer):
             metadata=metadata,
         )
 
+    def to_representation(self, instance):
+        d = {
+            'type': 'Audio',
+            'id': instance.get_federation_url(),
+            'name': instance.track.full_name,
+            'metadata': {
+                'artist': instance.track.artist.musicbrainz_url,
+                'release': instance.track.album.musicbrainz_url,
+                'track': instance.track.musicbrainz_url,
+            },
+            'url': {
+                'href': federation_utils.full_url(instance.path),
+                'type': 'Link',
+                'mediaType': instance.mimetype
+            },
+            'attributedTo': [
+                self.context['actor'].url
+            ]
+        }
+        if self.context.get('include_ap_context', True):
+            d['@context'] = AP_CONTEXT
+        return d
+
 
 class AudioCollectionImportSerializer(serializers.Serializer):
     id = serializers.URLField()
@@ -231,3 +256,24 @@ class AudioCollectionImportSerializer(serializers.Serializer):
             s = AudioSerializer(data=i)
             job = s.create(i, batch)
         return batch
+
+    def to_representation(self, instance):
+        d = {
+            'id': instance['id'],
+            'actor': instance['actor'].url,
+            'totalItems': len(instance['items']),
+            'type': 'Collection',
+            'items': [
+                AudioSerializer(
+                    i,
+                    context={
+                        'actor': instance['actor'],
+                        'include_ap_context': False
+                    }
+                ).data
+                for i in instance['items']
+            ]
+        }
+        if self.context.get('include_ap_context', True):
+            d['@context'] = AP_CONTEXT
+        return d
diff --git a/api/tests/music/test_serializers.py b/api/tests/music/test_serializers.py
index 556ac4c0e287f5031b5ede63d42dc9ebf5b85dbf..1270ae765e2e2ce52ec01732f1fb1f19641648d6 100644
--- a/api/tests/music/test_serializers.py
+++ b/api/tests/music/test_serializers.py
@@ -1,7 +1,10 @@
+from funkwhale_api.federation import actors
+from funkwhale_api.federation import utils as federation_utils
+from funkwhale_api.federation.serializers import AP_CONTEXT
 from funkwhale_api.music import serializers
 
 
-def test_activity_pub_audio_collection_serializer(factories):
+def test_activity_pub_audio_collection_serializer_to_import(factories):
     sender = factories['federation.Actor']()
 
     collection = {
@@ -30,3 +33,62 @@ def test_activity_pub_audio_collection_serializer(factories):
         assert job.source == a['url']['href']
         a['metadata']['mediaType'] = a['url']['mediaType']
         assert job.metadata == a['metadata']
+
+
+def test_activity_pub_audio_serializer_to_ap(factories):
+    tf = factories['music.TrackFile'](mimetype='audio/mp3')
+    library = actors.SYSTEM_ACTORS['library'].get_actor_instance()
+    expected = {
+        '@context': AP_CONTEXT,
+        'type': 'Audio',
+        'id': tf.get_federation_url(),
+        'name': tf.track.full_name,
+        'metadata': {
+            'artist': tf.track.artist.musicbrainz_url,
+            'release': tf.track.album.musicbrainz_url,
+            'track': tf.track.musicbrainz_url,
+        },
+        'url': {
+            'href': federation_utils.full_url(tf.path),
+            'type': 'Link',
+            'mediaType': 'audio/mp3'
+        },
+        'attributedTo': [
+            library.url
+        ]
+    }
+
+    serializer = serializers.AudioSerializer(tf, context={'actor': library})
+
+    assert serializer.data == expected
+
+
+def test_activity_pub_audio_collection_serializer_to_ap(factories):
+    tf1 = factories['music.TrackFile'](mimetype='audio/mp3')
+    tf2 = factories['music.TrackFile'](mimetype='audio/ogg')
+    library = actors.SYSTEM_ACTORS['library'].get_actor_instance()
+    expected = {
+        '@context': AP_CONTEXT,
+        'id': 'https://test.id',
+        'actor': library.url,
+        'totalItems': 2,
+        'type': 'Collection',
+        'items': [
+            serializers.AudioSerializer(
+                tf1, context={'actor': library, 'include_ap_context': False}
+            ).data,
+            serializers.AudioSerializer(
+                tf2, context={'actor': library, 'include_ap_context': False}
+            ).data,
+        ]
+    }
+
+    collection = {
+        'id': expected['id'],
+        'actor': library,
+        'items': [tf1, tf2],
+    }
+    serializer = serializers.AudioCollectionImportSerializer(
+        collection, context={'actor': library, 'id': 'https://test.id'})
+
+    assert serializer.data == expected