diff --git a/api/funkwhale_api/music/views.py b/api/funkwhale_api/music/views.py
index d8b173b4fe0d43db2ed3c150bdec1b57d3835b28..2f5b75a97a51de248fc128835c50d1b3b926ffd0 100644
--- a/api/funkwhale_api/music/views.py
+++ b/api/funkwhale_api/music/views.py
@@ -242,8 +242,8 @@ def get_file_path(audio_file):
                     'You need to specify MUSIC_DIRECTORY_SERVE_PATH and '
                     'MUSIC_DIRECTORY_PATH to serve in-place imported files'
                 )
-            path = audio_file.replace(prefix, serve_path, 1).encode('utf-8')
-        return path
+            path = audio_file.replace(prefix, serve_path, 1)
+        return path.encode('utf-8')
 
 
 def handle_serve(track_file):
diff --git a/api/funkwhale_api/subsonic/serializers.py b/api/funkwhale_api/subsonic/serializers.py
index 6709930f56756abae175f1158bae0f9d94ec67b7..f63ad5d2ee92885e5ec15713bfbf82d92ac2495a 100644
--- a/api/funkwhale_api/subsonic/serializers.py
+++ b/api/funkwhale_api/subsonic/serializers.py
@@ -57,8 +57,10 @@ class GetArtistSerializer(serializers.Serializer):
                 'name': album.title,
                 'artist': artist.name,
                 'created': album.creation_date,
-                'songCount': len(album.tracks.all())
+                'songCount': len(album.tracks.all()),
             }
+            if album.cover:
+                album_data['coverArt'] = 'al-{}'.format(album.id)
             if album.release_date:
                 album_data['year'] = album.release_date.year
             payload['album'].append(album_data)
@@ -81,6 +83,8 @@ def get_track_data(album, track, tf):
         'artistId': album.artist.pk,
         'type': 'music',
     }
+    if track.album.cover:
+        data['coverArt'] = 'al-{}'.format(track.album.id)
     if tf.bitrate:
         data['bitrate'] = int(tf.bitrate/1000)
     if tf.size:
@@ -98,6 +102,9 @@ def get_album2_data(album):
         'artist': album.artist.name,
         'created': album.creation_date,
     }
+    if album.cover:
+        payload['coverArt'] = 'al-{}'.format(album.id)
+
     try:
         payload['songCount'] = album._tracks_count
     except AttributeError:
diff --git a/api/funkwhale_api/subsonic/views.py b/api/funkwhale_api/subsonic/views.py
index 2692a3dda804ad22c07ee340012ad037afb5e42b..87c9f72700ca8dcd7e5cbfeb3fadb37edb6c7e11 100644
--- a/api/funkwhale_api/subsonic/views.py
+++ b/api/funkwhale_api/subsonic/views.py
@@ -1,5 +1,6 @@
 import datetime
 
+from django.conf import settings
 from django.utils import timezone
 
 from rest_framework import exceptions
@@ -459,7 +460,7 @@ class SubsonicViewSet(viewsets.GenericViewSet):
                     'code': 10,
                     'message': 'Playlist ID or name must be specified.'
                 }
-            }, data)
+            })
 
         playlist = request.user.playlists.create(
             name=name
@@ -503,3 +504,51 @@ class SubsonicViewSet(viewsets.GenericViewSet):
             }
         }
         return response.Response(data)
+
+    @list_route(
+        methods=['get', 'post'],
+        url_name='get_cover_art',
+        url_path='getCoverArt')
+    def get_cover_art(self, request, *args, **kwargs):
+        data = request.GET or request.POST
+        id = data.get('id', '')
+        if not id:
+            return response.Response({
+                'error': {
+                    'code': 10,
+                    'message': 'cover art ID must be specified.'
+                }
+            })
+        
+        if id.startswith('al-'):
+            try:
+                album_id = int(id.replace('al-', ''))
+                album = music_models.Album.objects.exclude(
+                    cover__isnull=True
+                ).exclude(cover='').get(pk=album_id)
+            except (TypeError, ValueError, music_models.Album.DoesNotExist):
+                return response.Response({
+                    'error': {
+                        'code': 70,
+                        'message': 'cover art not found.'
+                    }
+                })
+            cover = album.cover
+        else:
+            return response.Response({
+                'error': {
+                    'code': 70,
+                    'message': 'cover art not found.'
+                }
+            })
+
+        mapping = {
+            'nginx': 'X-Accel-Redirect',
+            'apache2': 'X-Sendfile',
+        }
+        path = music_views.get_file_path(cover)
+        file_header = mapping[settings.REVERSE_PROXY_TYPE]
+        # let the proxy set the content-type
+        r = response.Response({}, content_type='')
+        r[file_header] = path
+        return r
\ No newline at end of file
diff --git a/api/tests/subsonic/test_serializers.py b/api/tests/subsonic/test_serializers.py
index ad9f739a1dd63ae2036142b2bdab149dc9e63635..081b669c571cceff6d41fd973bfd8b3113a35a60 100644
--- a/api/tests/subsonic/test_serializers.py
+++ b/api/tests/subsonic/test_serializers.py
@@ -60,6 +60,7 @@ def test_get_artist_serializer(factories):
         'album': [
             {
                 'id': album.pk,
+                'coverArt': 'al-{}'.format(album.id),
                 'artistId': artist.pk,
                 'name': album.title,
                 'artist': artist.name,
@@ -88,11 +89,13 @@ def test_get_album_serializer(factories):
         'songCount': 1,
         'created': album.creation_date,
         'year': album.release_date.year,
+        'coverArt': 'al-{}'.format(album.id),
         'song': [
             {
                 'id': track.pk,
                 'isDir': 'false',
                 'title': track.title,
+                'coverArt': 'al-{}'.format(album.id),
                 'album': album.title,
                 'artist': artist.name,
                 'track': track.position,
diff --git a/api/tests/subsonic/test_views.py b/api/tests/subsonic/test_views.py
index bd445e070727c529e1295154c79302d0f37c51b1..65c2ad95f351ca2228f4d05fc835f34c4edaf1e7 100644
--- a/api/tests/subsonic/test_views.py
+++ b/api/tests/subsonic/test_views.py
@@ -391,3 +391,16 @@ def test_get_indexes(f, db, logged_in_api_client, factories):
 
     assert response.status_code == 200
     assert response.data == expected
+
+
+def test_get_cover_art_album(factories, logged_in_api_client):
+    url = reverse('api:subsonic-get-cover-art')
+    assert url.endswith('getCoverArt') is True
+    album = factories['music.Album']()
+    response = logged_in_api_client.get(url, {'id': 'al-{}'.format(album.pk)})
+
+    assert response.status_code == 200
+    assert response['Content-Type'] == ''
+    assert response['X-Accel-Redirect'] == music_views.get_file_path(
+        album.cover
+    ).decode('utf-8')
diff --git a/changes/changelog.d/258.enhancement b/changes/changelog.d/258.enhancement
new file mode 100644
index 0000000000000000000000000000000000000000..28f05c01bbee0b3af5a4aa54ac99ed461e1375e9
--- /dev/null
+++ b/changes/changelog.d/258.enhancement
@@ -0,0 +1 @@
+Implemented getCovertArt in Subsonic API to serve album covers (#258)
\ No newline at end of file