diff --git a/captcha.api.php b/captcha.api.php
new file mode 100644
index 0000000000000000000000000000000000000000..23ace70e46714971ccaf154ae9133027d2fe8265
--- /dev/null
+++ b/captcha.api.php
@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * @file
+ * Hooks for the captcha module.
+ */
+
+/**
+ * Implements hook_captcha().
+ *
+ * This documentation is for developers that want to implement their own
+ * challenge type and integrate it with the base CAPTCHA module.
+ * === Required: hook_captcha($op, $captcha_type='') ===
+ * The hook_captcha() hook is the only required function if you want to
+ * integrate with the base CAPTCHA module.
+ * Functionality depends on the first argument $op:
+ * 'list': you should return an array of possible challenge types that
+ * your module implements.
+ * 'generate': generate a challenge.
+ * You should return an array that offers form elements and the solution
+ * of your challenge, defined by the second argument $captcha_type.
+ * The returned array $captcha should have the following items:
+ * $captcha['solution']: this is the solution of your challenge
+ * $captcha['form']: an array of the form elements you want to add to the form.
+ * There should be a key 'captcha_response' in this array, which points to
+ * the form element where the user enters his answer.
+ * An optional additional argument $captcha_sid with the captcha session ID is
+ * available for more advanced challenges (e.g. the image CAPTCHA uses this
+ * argument, see image_captcha_captcha()) and it is used for every session.
+ * Let's give a simple example to make this more clear.
+ * We create the challenge 'Foo CAPTCHA', which requires the user to
+ * enter "foo" in a textfield.
+ */
+function foo_captcha_captcha($op, $captcha_type = '') {
+  switch ($op) {
+    case 'list':
+      return ['Foo CAPTCHA'];
+
+    case 'generate':
+      if ($captcha_type == 'Foo CAPTCHA') {
+        $captcha = [];
+        $captcha['solution'] = 'foo';
+        $captcha['form']['captcha_response'] = [
+          '#type' => 'textfield',
+          '#title' => t('Enter "foo"'),
+          '#required' => TRUE,
+        ];
+        // The CAPTCHA module provides an option for case sensitive and case
+        // insensitve validation of the responses. If this is not sufficient,
+        // you can provide your own validation function with the
+        // 'captcha_validate' field, illustrated by the following example:
+        $captcha['captcha_validate'] = 'foo_captcha_custom_validation';
+        return $captcha;
+      }
+      break;
+  }
+}
+
+/**
+ * Implements hook_menu().
+ *
+ * Validation of the answer against the solution and other stuff is done by the
+ * base CAPTCHA module.
+ * === Recommended: hook_menu($may_cache) ===
+ * More advanced CAPTCHA modules probably want some configuration page.
+ * To integrate nicely with the base CAPTCHA module you should offer your
+ * configuration page as a MENU_LOCAL_TASK menu entry under
+ * 'admin/config/people/captcha/'.
+ * For our simple foo CAPTCHA module this would mean:
+ */
+function foo_captcha_menu($may_cache) {
+  $items = [];
+  if ($may_cache) {
+    $items['admin/config/people/captcha/foo_captcha'] = [
+      'title' => t('Foo CAPTCHA'),
+      'page callback' => 'drupal_get_form',
+      'page arguments' => ['foo_captcha_settings_form'],
+      'type' => MENU_LOCAL_TASK,
+    ];
+  }
+  return $items;
+}
+
+/**
+ * Implements hook_help().
+ *
+ * You should of course implement a function foo_captcha_settings_form() which
+ * returns the form of your configuration page.
+ * === Optional: hook_help($section) ===
+ * To offer a description/explanation of your challenge, you can use the
+ * normal hook_help() system.
+ * For our simple foo CAPTCHA module this would mean:
+ */
+function foo_captcha_help($route_name, RouteMatchInterface $route_match) {
+  switch ($route_name) {
+    case 'foo_captcha.settings':
+      return '<p>' . t('This is a very simple challenge, which requires users to
+      enter "foo" in a textfield.') . '</p>';
+  }
+}
+
+/**
+ * Custom CAPTCHA validation function.
+ *
+ * Previous example shows the basic usage for custom validation with only a
+ * $solution and $response argument, which should be sufficient for most CAPTCHA
+ * modules. More advanced CAPTCHA modules can also use extra provided arguments
+ * $element and $form_state:
+ *
+ * @param $solution
+ *   the solution for the challenge as reported by hook_captcha('generate',...).
+ * @param $response
+ *   the answer given by the user.
+ *
+ * @return true
+ *   on success and FALSE on failure.
+ */
+function foo_captcha_custom_validation($solution, $response) {
+  return $response == "foo" || $response == "bar";
+}
+
+/**
+ * Custom Advance CAPTCHA validation function.
+ *
+ * These extra arguments are the $element and $form_state arguments of the
+ * validation function of the #captcha element. See captcha_validate() in
+ * captcha.module for more info about this.
+ *
+ * @param $solution
+ *   the solution for the challenge as reported by hook_captcha('generate',...).
+ * @param $response
+ *   the answer given by the user.
+ * @param $element
+ *   element argument.
+ * @param $form_state
+ *   form_state argument.
+ *
+ * @return true
+ *   on success and FALSE on failure.
+ */
+function foo_captcha_custom_advance_validation($solution, $response, $element, $form_state) {
+  return $form_state['foo']['#bar'] = 'baz';
+}
+
+/**
+ * Implements hook_captcha_placement_map().
+ *
+ * === Hook into CAPTCHA placement ===
+ * The CAPTCHA module attempts to place the CAPTCHA element in an appropriate
+ * spot at the bottom of the targeted form, but this automatic detection may be
+ * insufficient for complex forms.
+ * The hook_captcha_placement_map hook allows to define the placement of the
+ * CAPTCHA element as desired. The hook should return an array, mapping form IDs
+ * to placement arrays, which are associative arrays with the following fields:
+ * 'path': path (array of path items) of the form's container element in which
+ * the CAPTCHA element should be inserted.
+ * 'key': the key of the element before which the CAPTCHA element
+ * should be inserted. If the field 'key' is undefined or NULL, the CAPTCHA
+ * will just be appended in the container.
+ * 'weight': if 'key' is not NULL: should be the weight of the element defined
+ * by 'key'. If 'key' is NULL and weight is not NULL/unset: set the weight
+ * property of the CAPTCHA element to this value.
+ * For example:
+ * This will place the CAPTCHA element
+ * in the 'my_fancy_form' form inside the container $form['items']['buttons'],
+ * just before the element $form['items']['buttons']['sacebutton'].
+ * in the 'another_form' form at the toplevel of the form, with a weight 34.
+ */
+function hook_captcha_placement_map() {
+  return [
+    'my_fancy_form' => [
+      'path' => ['items', 'buttons'],
+      'key' => 'savebutton',
+    ],
+    'another_form' => [
+      'path' => [],
+      'weight' => 34,
+    ],
+  ];
+}
diff --git a/docs/api.md b/docs/api.md
deleted file mode 100644
index 64dcf4b666f06ba750a70f3b77ff2d8fdc267f32..0000000000000000000000000000000000000000
--- a/docs/api.md
+++ /dev/null
@@ -1,222 +0,0 @@
-This documentation is for developers that want to implement their own
-challenge type and integrate it with the base CAPTCHA module.
-
-
-=== Required: hook_captcha($op, $captcha_type='') ===
-
-The hook_captcha() hook is the only required function if you want to integrate
-with the base CAPTCHA module.
-Functionality depends on the first argument $op:
-  * 'list': you should return an array of possible challenge types
-    that your module implements.
-  * 'generate': generate a challenge.
-    You should return an array that offers form elements and the solution
-    of your challenge, defined by the second argument $captcha_type.
-    The returned array $captcha should have the following items:
-    $captcha['solution']: this is the solution of your challenge
-    $captcha['form']: an array of the form elements you want to add to the form.
-      There should be a key 'captcha_response' in this array, which points to
-      the form element where the user enters his answer.
-    An optional additional argument $captcha_sid with the captcha session ID is
-    available for more advanced challenges (e.g. the image CAPTCHA uses this
-    argument, see image_captcha_captcha()).
-
-Let's give a simple example to make this more clear.
-We create the challenge 'Foo CAPTCHA', which requires the user to
-enter "foo" in a textfield.
-
-"""
-/**
- * Implementation of hook_captcha().
- */
-function foo_captcha_captcha($op, $captcha_type='') {
-  switch ($op) {
-    case 'list':
-      return ['Foo CAPTCHA'];
-    case 'generate':
-      if ($captcha_type == 'Foo CAPTCHA') {
-        $captcha = [];
-        $captcha['solution'] = 'foo';
-        $captcha['form']['captcha_response'] = [
-          '#type' => 'textfield',
-          '#title' => t('Enter "foo"'),
-          '#required' => TRUE,
-        ];
-        return $captcha;
-      }
-      break;
-  }
-}
-"""
-
-Validation of the answer against the solution and other stuff is done by the
-base CAPTCHA module.
-
-
-
-
-=== Required: the .info file ===
-
-You should specify that your module depends on the base CAPTCHA module.
-Optionally you could put your module in the "Spam control" package.
-
-For our simple foo CAPTCHA module this would mean the following lines in the
-file foo_captcha.info:
-
-"""
-name = "Foo CAPTCHA"
-description = "The foo CAPTCHA requires the user to enter the word 'foo'."
-package = "Spam control"
-dependencies[] = captcha
-core = 6.x
-"""
-
-
-
-
-=== Recommended: hook_menu($may_cache) ===
-
-More advanced CAPTCHA modules probably want some configuration page.
-To integrate nicely with the base CAPTCHA module you should offer your
-configuration page as a MENU_LOCAL_TASK menu entry under
-'admin/config/people/captcha/'.
-
-For our simple foo CAPTCHA module this would mean:
-
-"""
-/**
- * Implementation of hook_menu().
- */
-function foo_captcha_menu($may_cache) {
-  $items = [];
-  if ($may_cache) {
-    $items['admin/config/people/captcha/foo_captcha'] = [
-      'title' => t('Foo CAPTCHA'),
-      'page callback' => 'drupal_get_form',
-      'page arguments' => ['foo_captcha_settings_form'],
-      'type' => MENU_LOCAL_TASK,
-    ];
-  }
-  return $items;
-}
-"""
-
-You should of course implement a function foo_captcha_settings_form() which
-returns the form of your configuration page.
-
-
-
-
-=== Optional: hook_help($section) ===
-To offer a description/explanation of your challenge, you can use the
-normal hook_help() system.
-
-For our simple foo CAPTCHA module this would mean:
-
-"""
-/**
- * Implementation of hook_help().
- */
-function foo_captcha_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'foo_captcha.settings':
-      return '<p>'. t('This is a very simple challenge, which requires users to
-      enter "foo" in a textfield.') .'</p>';
-  }
-}
-"""
-
-
-
-=== Optional: custom response validation ===
-The CAPTCHA module provides an option for case sensitive and case insensitve
-validation of the responses. If this is not sufficient, you can provide
-your own validation function with the 'captcha_validate' field, illustrated
-by the following example:
-
-"""
-/**
- * Implementation of hook_captcha().
- */
-function foo_captcha_captcha($op, $captcha_type='') {
-  switch ($op) {
-    ...
-    case 'generate':
-      if ($captcha_type == 'Foo CAPTCHA') {
-        $captcha = [];
-        $captcha['solution'] = ...
-        $captcha['form'] = ...
-        $captcha['captcha_validate'] = 'foo_captcha_custom_validation';
-        return $captcha;
-      }
-      break;
-  }
-}
-
-/**
- * Custom CAPTCHA validation function.
- *
- * @param solution the solution for the challenge as reported by
-    hook_captcha('generate', ...).
- * @param response the answer given by the user.
- * @return TRUE on succes and FALSE on failure.
- */
-function foo_captcha_custom_validation($solution, $response) {
-  return $response == "foo" || $response == "bar";
-}
-"""
-
-Previous example shows the basic usage for custom validation with only a
-$solution and $response argument, which should be sufficient for most CAPTCHA
-modules. More advanced CAPTCHA modules can also use extra provided arguments
-$element and $form_state:
-"""
-function foo_captcha_custom_validation($solution, $response, $element,
-  $form_state) {
-  return $form_state['foo']['#bar'] = 'baz';
-}
-"""
-These extra arguments are the $element and $form_state arguments of the
-validation function of the #captcha element. See captcha_validate() in
-captcha.module for more info about this.
-
-
-
-=== Hook into CAPTCHA placement ===
-The CAPTCHA module attempts to place the CAPTCHA element in an appropriate spot
-at the bottom of the targeted form, but this automatic detection may be
-insufficient for complex forms.
-The hook_captcha_placement_map hook allows to define the placement of the
-CAPTCHA element as desired. The hook should return an array, mapping form IDs
-to placement arrays, which are associative arrays with the following fields:
-  - 'path': path (array of path items) of the form's container element in which
-    the CAPTCHA element should be inserted.
-  - 'key': the key of the element before which the CAPTCHA element
-    should be inserted. If the field 'key' is undefined or NULL, the CAPTCHA
-    will just be appended in the container.
-  - 'weight': if 'key' is not NULL: should be the weight of the element defined
-    by 'key'. If 'key' is NULL and weight is not NULL/unset: set the weight
-    property of the CAPTCHA element to this value.
-
-For example:
-"""
-/**
- * Implementation of hook_captcha_placement_map
- */
-function hook_captcha_placement_map() {
-  return [
-    'my_fancy_form' => [
-      'path' => ['items', 'buttons'],
-      'key' => 'savebutton',
-    ],
-    'another_form' => [
-      'path' => [],
-      'weight' => 34,
-    ],
-  ];
-}
-"""
-This will place the CAPTCHA element
-  - in the 'my_fancy_form' form inside the container $form['items']['buttons'],
-    just before the element $form['items']['buttons']['sacebutton'].
-  - in the 'another_form' form at the toplevel of the form, with a weight 34.