diff --git a/beat/web/experiments/api.py b/beat/web/experiments/api.py
index b21eb32c6111cb6e00a9d15a50d019c34d203cf7..e82b7c1f77c83ef2edaf82a72ae51208d2360450 100755
--- a/beat/web/experiments/api.py
+++ b/beat/web/experiments/api.py
@@ -25,9 +25,6 @@
 #                                                                             #
 ###############################################################################
 
-import re
-import uuid
-
 import simplejson
 import functools
 
@@ -49,7 +46,11 @@ import beat.core.algorithm
 import beat.core.toolchain
 
 from .models import Experiment
-from .serializers import ExperimentSerializer, ExperimentResultsSerializer
+from .serializers import (
+    ExperimentSerializer,
+    ExperimentResultsSerializer,
+    ExperimentCreationSerializer,
+)
 from .permissions import IsDatabaseAccessible
 
 from ..common.responses import BadRequestResponse, ForbiddenResponse
@@ -102,10 +103,8 @@ class ListCreateExperimentsView(ListCreateContributionView):
 
     model = Experiment
     serializer_class = ExperimentSerializer
-
-    # TODO: no serializer is used by the POST method, but the rest-framework isn't
-    # happy if we don't declare one
-    writing_serializer_class = ExperimentSerializer
+    writing_serializer_class = ExperimentCreationSerializer
+    namespace = "api_experiments"
 
     def get(self, request, author_name):
         def _getStatusLabel(status):
@@ -174,134 +173,6 @@ class ListCreateExperimentsView(ListCreateContributionView):
         # Returns the results
         return Response(processed_result)
 
-    def post(self, request, author_name):
-        data = request.data
-
-        if "name" in data:
-            if not (isinstance(data["name"], six.string_types)):
-                return BadRequestResponse("Invalid name")
-
-            max_length = self.model._meta.get_field("name").max_length
-            current_length = len(data["name"])
-            if current_length > max_length:
-                return BadRequestResponse(
-                    "name too long, max is {}, current is {}".format(
-                        max_length, current_length
-                    )
-                )
-
-            name = re.sub(r"[\W]", "-", data["name"])
-        else:
-            name = None
-
-        if "short_description" in data:
-            if not (isinstance(data["short_description"], six.string_types)):
-                return BadRequestResponse("Invalid short_description")
-
-            max_length = self.model._meta.get_field("short_description").max_length
-            current_length = len(data["short_description"])
-            if current_length > max_length:
-                return BadRequestResponse(
-                    "Short description too long, max is {}, current is {}".format(
-                        max_length, current_length
-                    )
-                )
-
-            short_description = data["short_description"]
-        else:
-            short_description = ""
-
-        if "description" in data:
-            if not (isinstance(data["description"], six.string_types)):
-                raise serializers.ValidationError(
-                    {"description": "Invalid description data"}
-                )
-            description = data["description"]
-            try:
-                validate_restructuredtext(description)
-            except ValidationError as errors:
-                raise serializers.ValidationError(
-                    {"description": [error for error in errors]}
-                )
-        else:
-            description = None
-
-        if "toolchain" not in data:
-            return BadRequestResponse("Must indicate a toolchain name")
-
-        if not (isinstance(data["toolchain"], six.string_types)):
-            return BadRequestResponse("Invalid toolchain name")
-
-        if "declaration" not in data:
-            return BadRequestResponse("Must indicate a declaration")
-
-        if not (isinstance(data["declaration"], dict)) and not (
-            isinstance(data["declaration"], six.string_types)
-        ):
-            return BadRequestResponse("Invalid declaration")
-
-        if isinstance(data["declaration"], dict):
-            declaration = data["declaration"]
-        else:
-            declaration_string = data["declaration"]
-            try:
-                declaration = simplejson.loads(declaration_string)
-            except simplejson.errors.JSONDecodeError:
-                return BadRequestResponse("Invalid declaration data")
-
-        # Retrieve the toolchain
-        core_toolchain = beat.core.toolchain.Storage(settings.PREFIX, data["toolchain"])
-
-        if core_toolchain.version == "unknown":
-            return BadRequestResponse("Unknown toolchain version")
-
-        if core_toolchain.username is None:
-            core_toolchain.username = request.user.username
-
-        try:
-            db_toolchain = Toolchain.objects.for_user(request.user, True).get(
-                author__username=core_toolchain.username,
-                name=core_toolchain.name,
-                version=core_toolchain.version,
-            )
-        except Toolchain.DoesNotExist:
-            return Response("Toolchain %s not found" % data["toolchain"], status=404)
-
-        # Create the experiment object in the database
-        existing_names = map(
-            lambda x: x.name,
-            Experiment.objects.filter(author=request.user, toolchain=db_toolchain),
-        )
-        if name is None:
-            name = str(uuid.uuid4())
-            while name in existing_names:
-                name = str(uuid.uuid4())
-
-        elif name in existing_names:
-            return BadRequestResponse("The name '" + name + "' is already used")
-
-        experiment, toolchain, errors = Experiment.objects.create_experiment(
-            author=request.user,
-            toolchain=db_toolchain,
-            name=name,
-            short_description=short_description,
-            description=description,
-            declaration=declaration,
-        )
-
-        if not experiment:
-            return BadRequestResponse(errors)
-
-        # Send the result
-        result = {
-            "name": experiment.fullname(),
-            "url": reverse("api_experiments:all") + experiment.fullname() + "/",
-        }
-
-        response = Response(result, status=201)
-        response["Location"] = result["url"]
-        return response
-
 
 # ----------------------------------------------------------