diff --git a/doc/rapi.rst b/doc/rapi.rst
index 9d95c81470c75cd77021138da3a51fe0d2209216..1a9294d407d4b71565af8694b814775fa119d844 100644
--- a/doc/rapi.rst
+++ b/doc/rapi.rst
@@ -334,6 +334,22 @@ instance if even if secondary disks are failing.
 It supports the ``dry-run`` argument.
 
 
+``/2/instances/[instance_name]/replace-disks``
+++++++++++++++++++++++++++++++++++++++++++++++
+
+Replaces disks on an instance.
+
+It supports the following commands: ``POST``.
+
+``POST``
+~~~~~~~~
+
+Takes the parameters ``mode`` (one of ``replace_on_primary``,
+``replace_on_secondary``, ``replace_new_secondary`` or ``replace_auto``),
+``disks`` (comma separated list of disk indexes), ``remote_node`` and
+``iallocator``.
+
+
 ``/2/instances/[instance_name]/tags``
 +++++++++++++++++++++++++++++++++++++
 
diff --git a/lib/rapi/connector.py b/lib/rapi/connector.py
index 59621a9e5611dad0a28a34b6d160d4ec18bac825..d82780b51a56261e30ea2bf2f9c7d6b8336d9956 100644
--- a/lib/rapi/connector.py
+++ b/lib/rapi/connector.py
@@ -170,6 +170,8 @@ CONNECTOR.update({
       rlib2.R_2_instances_name_reboot,
   re.compile(r'^/2/instances/([\w\._-]+)/reinstall$'):
       rlib2.R_2_instances_name_reinstall,
+  re.compile(r'^/2/instances/([\w\._-]+)/replace-disks$'):
+      rlib2.R_2_instances_name_replace_disks,
   re.compile(r'^/2/instances/([\w\._-]+)/shutdown$'):
       rlib2.R_2_instances_name_shutdown,
   re.compile(r'^/2/instances/([\w\._-]+)/startup$'):
diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index 7042974e368a0bbab3a6949f75f5e256a7912c40..3a398a572368ea7f500da5944593e683ae04541b 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -550,6 +550,37 @@ class R_2_instances_name_reinstall(baserlib.R_Generic):
     return baserlib.SubmitJob(ops)
 
 
+class R_2_instances_name_replace_disks(baserlib.R_Generic):
+  """/2/instances/[instance_name]/replace-disks resource.
+
+  """
+  def POST(self):
+    """Replaces disks on an instance.
+
+    """
+    instance_name = self.items[0]
+    remote_node = self._checkStringVariable("remote_node", default=None)
+    mode = self._checkStringVariable("mode", default=None)
+    raw_disks = self._checkStringVariable("disks", default=None)
+    iallocator = self._checkStringVariable("iallocator", default=None)
+
+    if raw_disks:
+      try:
+        disks = [int(part) for part in raw_disks.split(",")]
+      except ValueError, err:
+        raise http.HttpBadRequest("Invalid disk index passed: %s" % str(err))
+    else:
+      disks = []
+
+    op = opcodes.OpReplaceDisks(instance_name=instance_name,
+                                remote_node=remote_node,
+                                mode=mode,
+                                disks=disks,
+                                iallocator=iallocator)
+
+    return baserlib.SubmitJob([op])
+
+
 class _R_Tags(baserlib.R_Generic):
   """ Quasiclass for tagging resources