diff --git a/swh/core/api.py b/swh/core/api/__init__.py
similarity index 100%
rename from swh/core/api.py
rename to swh/core/api/__init__.py
diff --git a/swh/core/api/asynchronous.py b/swh/core/api/asynchronous.py
new file mode 100644
index 0000000000000000000000000000000000000000..eed981ed68c7bb332f00aa15a167cb518e530964
--- /dev/null
+++ b/swh/core/api/asynchronous.py
@@ -0,0 +1,56 @@
+import aiohttp.web
+import asyncio
+import json
+import logging
+import multidict
+import pickle
+import sys
+import traceback
+
+from .serializers import msgpack_dumps, msgpack_loads, SWHJSONDecoder
+
+
+def encode_data_server(data, **kwargs):
+    return aiohttp.web.Response(
+        body=msgpack_dumps(data),
+        headers=multidict.MultiDict({'Content-Type': 'application/x-msgpack'}),
+        **kwargs
+    )
+
+
+@asyncio.coroutine
+def decode_request(request):
+    content_type = request.headers.get('Content-Type')
+    data = yield from request.read()
+
+    if content_type == 'application/x-msgpack':
+        r = msgpack_loads(data)
+    elif content_type == 'application/json':
+        r = json.loads(data, cls=SWHJSONDecoder)
+    else:
+        raise ValueError('Wrong content type `%s` for API request'
+                         % content_type)
+    return r
+
+
+@asyncio.coroutine
+def error_middleware(app, handler):
+    @asyncio.coroutine
+    def middleware_handler(request):
+        try:
+            return (yield from handler(request))
+        except Exception as e:
+            if isinstance(e, aiohttp.web.HTTPException):
+                raise
+            logging.exception(e)
+            exception = traceback.format_exception(*sys.exc_info())
+            res = {'exception': exception,
+                   'exception_pickled': pickle.dumps(e)}
+            return encode_data_server(res, status=500)
+    return middleware_handler
+
+
+class SWHRemoteAPI(aiohttp.web.Application):
+    def __init__(self, *args, middlewares=(), **kwargs):
+        middlewares = (error_middleware,) + middlewares
+        super().__init__(*args, middlewares=middlewares, **kwargs)
diff --git a/swh/core/serializers.py b/swh/core/api/serializers.py
similarity index 100%
rename from swh/core/serializers.py
rename to swh/core/api/serializers.py
diff --git a/swh/core/api_async.py b/swh/core/api_async.py
index eed981ed68c7bb332f00aa15a167cb518e530964..95025822792df6b5ef84147fec684861b06f338b 100644
--- a/swh/core/api_async.py
+++ b/swh/core/api_async.py
@@ -1,56 +1 @@
-import aiohttp.web
-import asyncio
-import json
-import logging
-import multidict
-import pickle
-import sys
-import traceback
-
-from .serializers import msgpack_dumps, msgpack_loads, SWHJSONDecoder
-
-
-def encode_data_server(data, **kwargs):
-    return aiohttp.web.Response(
-        body=msgpack_dumps(data),
-        headers=multidict.MultiDict({'Content-Type': 'application/x-msgpack'}),
-        **kwargs
-    )
-
-
-@asyncio.coroutine
-def decode_request(request):
-    content_type = request.headers.get('Content-Type')
-    data = yield from request.read()
-
-    if content_type == 'application/x-msgpack':
-        r = msgpack_loads(data)
-    elif content_type == 'application/json':
-        r = json.loads(data, cls=SWHJSONDecoder)
-    else:
-        raise ValueError('Wrong content type `%s` for API request'
-                         % content_type)
-    return r
-
-
-@asyncio.coroutine
-def error_middleware(app, handler):
-    @asyncio.coroutine
-    def middleware_handler(request):
-        try:
-            return (yield from handler(request))
-        except Exception as e:
-            if isinstance(e, aiohttp.web.HTTPException):
-                raise
-            logging.exception(e)
-            exception = traceback.format_exception(*sys.exc_info())
-            res = {'exception': exception,
-                   'exception_pickled': pickle.dumps(e)}
-            return encode_data_server(res, status=500)
-    return middleware_handler
-
-
-class SWHRemoteAPI(aiohttp.web.Application):
-    def __init__(self, *args, middlewares=(), **kwargs):
-        middlewares = (error_middleware,) + middlewares
-        super().__init__(*args, middlewares=middlewares, **kwargs)
+from swh.core.api.asynchronous import *  # noqa, for bw compat
diff --git a/swh/core/tests/test_serializers.py b/swh/core/tests/test_serializers.py
index f9e80e966d336cb7d8481a179f4c924b39679763..40aec9a188d1668e435ff4e414c460af0d5f14e2 100644
--- a/swh/core/tests/test_serializers.py
+++ b/swh/core/tests/test_serializers.py
@@ -10,7 +10,7 @@ from uuid import UUID
 
 import arrow
 
-from swh.core.serializers import (
+from swh.core.api.serializers import (
     SWHJSONDecoder,
     SWHJSONEncoder,
     msgpack_dumps,